Dockerised Jenkins for mobile CI/CD— Part 1

--

When it comes to the use of Continuous Integration and Continuous Deployment for integrating to your mobile development workflow, mobile development is surely not different from other development process. On the other hand, the whole implementation of CI/CD for your environment (mobile, web) might be a challenge if you don’t know the basics well. As a developer the starting point to enter the CI/CD world is to know the base concepts and some automation automation tools for your project. So, the purpose of this post is to help you with the whole implementation of CI/CD for mobile development by using powerful technologies such us Docker and Jenkins.

Key Concepts

Docker — An open platform for developer, sysadmin to build, ship and run any app anywhere. Docker allows operating system level virtualization.

Jenkins — The leading open source automation server, Jenkins provides hundreds of plugins to support building, deploying and automating any project.

Android SDK — The Standard Development Kit for Android. The SDK is composed of multiple packages that are require app development. Important command line tools such as: sdkmanager, lint, avdmanager, apkanalyzer, adb, emulator, etc.

Gradle — An open-source build automation system that builds upon the concepts of Apache Ant and Apache Maven and introduces a Groovy-based domain-specific language(DSL) instead of XML used by Apache Maven. Gradle accelerate developer productivity and helps teams build, automate and deliver better software, faster.

Running Jenkins using Docker

Imagine we just want to install Jenkins for development purpose, so we would have to install Jenkins completely on our Operating System(linux, mac, windows), we would be adding installation files to our FileSystem and when we already have finished, we’ll need to uninstall it completely, this is not an easy process and requires long time. However, if we use Docker everything is clean, we can start and stop container in a fraction of a second. So, in order to run a Jenkins container, we need to visit the official Jenkins Docker image and run the following command.

docker run -p 8080:8080 -p 50000:50000 jenkins/jenkins:lts
Dockerised Jenkins

Once the container is running, you will see logs output in your terminal. Pay attention to the password shown below, because Jenkins will require it later in order to be logged into the console.

Open another terminal and run the docker ps command in order to see the status of the running container:

Open your browser and go to http:localhost:8080/jenkins

At this point, we need to use the password shown in the log output terminal and hit the Continue button. But If you couldn’t see the password, the second way is to access to the Jenkins docker container and see the content of the initialAdminPassword file. For this purpose, let’s enter inside the container and execute the cat command line tool in order to see the password:

After hit the Continue button, we’ll be prompted to installed Jenkins plugins. For now, let us only install the suggested plugins(some of them are the git and gradle plugins to clone our repositories and assemble our android builds respectively). Later, we’ll be able to install much more of them, or install only those necessary for you.

After install the suggested plugins, let’s Create a First Admin User such as the example below because Jenkins always requires a use account to be logged into the Jenkins console. Then click on Save and Continue button.

By default the Jenkins server listens on 8080 port. The Jenkins URL is so important if you want to access from another environment. This time, we are just standing our server up locally. However, because of the portability of containers we can run our Jenkins docker container whether on a user’s laptop, on data centers VM’s or in the cloud with a public IP without any problem. Let’s click on Save and Finish.

Now, we are ready to use Jenkins automation server. Let’s rest for a couple of minutes, get a cup of coffe and get on with it.

Finally, let me introduce you to the Jenkins console. Here you will be able to:

  • Use hundreds of open source plugins that make it easier the automation process for your project.
  • Build, run and ship any project(web, mobile, backend) and see all these processes through the famous pipelines.
  • Use continuous integration, continuous delivery and continuous deployment processes.
  • Be able to connect to remote machines called nodes trough the JPNL protocol integrated with Jenkins.
  • Manage users permissions and a lot of much more things.

Creating a Dev Freestyle project Job for Android

In order to create our continuous integration server for android apps, let’s hit the create new jobs button and set-up our android project. First of all, we need to provide our job’s name that is dev.androidtest.ci which consists of the following structure role.project_name.development_process, this name has a purpose which will be talked about later in the next post. And now, we will select the Freestyle project job which provides us features for continuous integration and click on the OK button, you can read much more about jobs types at the official website.

Jenkins can be used to perform the typical build server work, such as doing continuous/official/nightly builds, run tests, or perform some repetitive batch tasks. This is called “free-style software project” in Jenkins.

Setting-up Freestyle project job for android

For this purpose, we are going to use this DemoProject that is available on Github and already has android unit test and instrumentation test. We’ll see five tabs which are General, Source Code Management, Build Triggers, Build Environment, Build and Post-build Actions. Each of which will allow us to manage our continuous integration flow. In a very simple way, we will only set-up three of them.

Under General, check the Github project box and add your Github repository url. Example: https://github.com/orbismobile/android-TestingForAndroid

Under Source Code Management, choose “Git” and add the git repository. Example: https://github.com/orbismobile/android-TestingForAndroid.git We can also specify the branch to build our project, on my case is the alpha branch. The purpose of the Dev environment is to provide insight into what is currently on the debug branch. If you want to know a better branching strategy, I recommend you to read this amazing post.

Under Build section, click on Add build step > Invoke Gradle script > Use Gradle Wrapper and on the “Tasks” section add assembleDebug and testDebugUnitTest as we want Gradle to build the apk and run unit test respectively. For now, we are not going to run connectedDebugAndroidTest task which run the ui tests because it’s a little bit more complicated, it needs some prerequisites which we’ll talk about it later in the second part.

Finally, let’s Apply the changes and click on the Save button.

Building the Dev Freestyle Job

Now, we are ready to build the project, but since it’s an Android Project we are supposed to have the Android SDK. However, we are using a docker container which means that we need the Android SDK inside the container in order to run the Android Project with the specific API version.

Access to the Jenkins Docker container

To access to the docker container just, execute the following commands:

#shows the running containers
docker ps
#access to container's bash
docker exec -i -t {CONTAINER_ID} bash
#we are inside the docker container :)
jenkins@c234993d5583:/$

The jenkins@c234993d5583 indicates the username and the container_id respectively, by default the container is logged in with the jenkins user.

Download the Android SDK inside the container

First off, just download the Android SDK for Linux platform, because Jenkins image is based on Linux. Don’t forget that the right way to unpack and place the download SDK is described at the official documentation about installing Android Studio.

Unpack the .zip file you downloaded to an appropriate location for your applications, such as within /usr/local/ for your user profile, or /opt/ for shared users.

OK, Let’s follow what the official doc says, inside the docker container go to /usr/local or the /opt/ path and try to download the SDK:

jenkins@c234993d5583:~$ cd /opt
jenkins@c234993d5583:/opt$ curl -o sdk.zip https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip

Unfortunately, we’ll get the following error 0Warning: Failed to create the file sdk.zip: Permission denied. And why? Because the Jenkins user doesn’t have the necessary permissions to create folders inside these paths. Now, we have two options:

  1. Download the Android SDK in the path /var/jenkins_home (JENKINS_HOME), which is the workspace of jenkins user and has permissions where will create our sdk folder.
  2. Access to the container as a root user and be able to download and unzip the SDK in those paths (/usr/local/ or /opt/), but after this we will have to enter the container as a jenkins user on more time.
docker exec -u 0 -i -t c234993d5583 bash #to access as a root

The first option sounds good, the only backward is that the android sdk is not light-weight and what would happen if we want to share this folder with other containers in the future?. So, Maybe the don’t need the android SDK and should be separated in another folder but it depends on you.

Ok, for practical purposes, let’s continue with the first option and download the SDK, inside the docker container with the jenkins@c234993d5583 user:

cd /var/jenkins_home
curl -o sdk.zip https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip
unzip -d sdk sdk.zip
rm -rf sdk.zip

Go to Manage Jenkins > Configure System > Global Properties and check the box Environment variables. Add ANDROID_HOME variable and its path /var/jenkins_home/sdk, click Apply and Save.

Let’s Build Now the job and most likely we haven’t downloaded yet the Android Api version required by our android project. The error is clean, the DemoProject required the Android SDK Platform 26 and Android sdk Build-Tools 26.0.2 packages.

So, let’s install these packages using the android SDK, inside the Jenkins docker container, go to /var/jenkins_home/sdk/tools/bin path and run the sdkmanager tool to download the required libraries.

cd /var/jenkins_home/sdk/tools/bin/
./sdkmanager "platforms;android-26" "build-tools;26.0.2"

We’ll be prompted to accept terms and conditions, type y and enter.

Let us Build Now the job and everything will be successful. Happy coding ❤

The final successful build

Up Next: Dockerized Jenkins for mobile CI/CD — PART 2. In this next part we’ll see how to further automate all this process by using a Dockerfile and understand the JNLP(Java Network Launch Protocol) which allows us to create Master-Node slaves as a key option for Running Android Instrumentation Test.

--

--