Setting Up Jenkins For Android: How I dealt with the challenges I faced
In this article, I will document my journey to achieve a fully working continuous integration system using Jenkins. This setup suits my work environment which has multiple projects using the same 4 modules for business logic.
Firstly, I downloaded Jenkins from the official website. Then I opened the terminal and ran the following command:
java -jar jenkins.war --httpPort=9091
I specified a different port than the usual 8080 to make it unique and avoid any errors, in case another service is using Jenkins.
After completing all the setup steps, it is important to ensure that the following plugins are installed:
These plugins will ensure that Jenkins has the sufficient tools to build an Android project.
The next step is to setup up the following settings in Jenkins:
- Setting up JDK for Jenkins
I discovered the JDK section to look as follows after clicking Manage Jenkins -> Global Tool Configuration:
I then clicked Add JDK then filled up the following form:
I typed a name that represents the version selected and chose the version from Install from java.sun.com (Note: Jenkins will ask about your Oracle account info in order to install the JDK).
On the same Global Tool Configuration page, I then found the Gradle plugin settings in which I added a Gradle installation that has the same version as the Gradle used in my projects. To avoid further confusion, I run projects with Gradle wrapper which I will discuss in more depth in the upcoming section.
I also made sure that the name represents the version selected to avoid confusion.
Normally, Gradle will search the local.properties file in the project to retrieve the Android SDK location. But when using Jenkins, I discovered that this might not always be the case, especially when using the Gradle wrapper.
To avoid build errors, I added ANDROID_HOME in the Jenkins environment variables. This is achieved through Manage Jenkins -> Configure System then checking the environment variables box in here:
and adding a variable with the name ANDROID_HOME and filling the value with the path to the SDK.
After achieving all these steps, I started to create a new item in Jenkins. Most of my projects rely on 4 main android modules which are included in the Git repository as Git submodules.
Setting up a new item is pretty easy if you don’t have any submodules:
Simply enter the name and select Freestyle project and hit OK.
Next, go to Source Code Management. I normally use Git and setup the repo:
Insert the repo URL and add credentials if you haven’t already. Now the trick here is to ensure that if you are using an HTTPS link for the repo, then you need to add username and password type credentials, else if using SSH then add the SSH type credentials.
If you have submodules in the git repo, then the easiest way to deal with this is through Additional behaviour -> Add ->Advanced sub-modules behaviours and doing the following:
- Check recursively update submodules
- In Path of the reference repo to use during submodule update, add the submodule folder name which is used in the parent repo.
- In my case, both parent and submodules can use the same credentials so I checked Use credentials from default remote of parent repository.
Add as many of those as the number of submodules included and also ensure that if the parent repo url is HTTPS, then the submodules link inside .gitmodules should also use HTTPS. The same applies for SSH.
In order to successfully build the project, Jenkins needs to invoke the Gradle script. The most efficient way is to tell Jenkins to execute the project’s Gradle wrapper and define the tasks (clean, assembleDebug, etc...)
In order to avoid permission denied error, Make Gradlew executable is checked and the tasks are specified.
Jenkins includes a wide variety of actions to be taken when the build is completed.
The most straight forward way to automatically publish the project on the play store using the Android play store publishing plugins can be found here.
A few remarks on publishing to the store
When submitting a new APK to the store, the version code needs to be incremented. To automate this, I made this snippet for reference.
In addition, when adding theRecent Changes part in Jenkins, make sure that you select the same language as the language found in the description for the store listing:
The final section is how to trigger builds automatically. For my project, the version control of my choice is bitbucket. In order to set it up, I followed this wiki. However there is a catch, for the webhooks to work you need to have Jenkins on a web server setting. Initially, I didn’t so the webhook didn’t work. I overcame this by triggering other builds after a certain project is successfully built. This solved my problem as I mainly develop the 4 main submodules in a dummy project then pull them in all the other projects.
This can be done in the Build Triggers Section just above Build:
My future steps will be to take advantage of Jenkins and automated testing, both through jUnit tests and Android instrumentation tests.
I hope you found this helpful — please share with me in the Comments section your feedback and similar challenges you had and how you overcame them. I’m more than happy to answer any questions you might have.