The software development community thrives on collaboration. The overarching idea is that, if everyone contributes, we can build the best possible code. The open source movement is one extension of this idea, supporting the philosophy that developers should openly share and modify each others’ code, working cooperatively to create the best-quality programs. Another extension of the idea is the practice of continuous integration (CI), first proposed and named in 1991 by software engineer Grady Booch, which introduced the idea that all developer working copies could be merged to a mainline on an ongoing basis. The goal is to prevent the “integration hell” universally dreaded by developers. Tools like Jenkins, TeamCity, Bamboo, GoCD, GitLab CI, and Travis CI integrate with GitHub and other platforms to provide CI support for builds.
Here at Distillery, we’re genuinely passionate about promoting knowledge and code sharing within the development community. To see the vast range of what we’ve shared, just take a quick scroll down our blog. For representative examples of developer knowledge sharing, check out our blogs on getting Kubernetes, an open source container management system, running on top of AWS; improving your documentation by uniting Swagger and Node.js; and using developer tools such as Apple’s Developer site, the Google Cloud Vision API, and the Affective Emotion Recognition SDK in our attempt to create customized emoji. In the same spirit, the blog below, written by Dmitriy Sitnikov and first published in 2017, explains how to put Travis CI — a highly trusted CI solution that’s free for all open source projects — to work on your Android projects.
Modern software development is far more “user”- friendly to developers than it used to be. GitHub, Heroku, and the huge Fabric family of tools make code review easy, deploy painless, and health monitoring pleasant. And when it comes to continuous integration, there is an easy solution as well. Travis is going to replace awkward Jenkins and Bamboo and hyper-functional TeamCity with a familiar “show me what to build and I’ll do the rest solution”. But unlike Node.js/Python/Rails projects, it just doesn’t work that way for Android. If you still want your fancy new mobile projects to be continuously tested and pull-requests checked automatically without wanting to spend your entire evening resolving Travis issues, we at Distillery have a solution.
So, to make Travis work, you need to add a simple .travis.yml configuration file to the project’s root folder and push it to GitHub. GitHub integration is as simple as one-two-click, and there is a sample of the Android config which is already obsolete, so you have to update it.
The first thing you need to know about Travis is that it doesn’t build Android in the MacOS environment at the moment, and for Linux Oracle’s Java is not the default, so let’s start by changing from
language: android jdk: oraclejdk8
Secondly, if you want your build tools version fresh and relevant to supported android version, I recommend you store that version as a constant, because you’ll need it in many places and I bet you’ll update the config much more often than Travis doc is updated. So, your next step is
env: global: - ANDROID_API_LEVEL=25 - ANDROID_BUILD_TOOLS_VERSION=25.0.2
Thirdly, Travis will not resolve dependencies for you like, for example, Heroku does for Python modules, so here we’ll use our variables. Let’s add all the main modules we’re going to use:
android: components: - tools - platform-tools # The BuildTools version used by your project - build-tools-$ANDROID_BUILD_TOOLS_VERSION # The SDK version used to compile your project - android-$ANDROID_API_LEVEL # Additional components - extra-google-google_play_services - extra-google-m2repository - extra-android-m2repository - addon-google_apis-google-$ANDROID_API_LEVEL
The names here are exactly the same as you can get running following command:
android list sdk --extended --no-ui --all
Fourthly, Google requires you to accept their license agreement before you can get their libraries and tools. Good news is that Travis can accept it for you by regexp, just add it under the android section:
licenses: - 'android-sdk-preview-license-.+' - 'android-sdk-license-.+' - 'google-gdk-license-.+'
The bad news is that it will not work for certain new libraries, such as the recently released ConstraintLayout. Well, don’t worry, I have a solution for you, as a manually accepted license can be exported to any machine, so just copy the license folder from your $ANDROID_HOME/licenses to your project and keep it along with the code. Next, a couple of lines will export the license files from your source directory to the proper place, so Travis won’t get stuck at this step anymore (I gave my source folder the name google-licenses to make it more specific):
before_script: - mkdir -p "$ANDROID_HOME/licenses" - cp ./google-licenses/* "$ANDROID_HOME/licenses/"
And lastly: Travis uses the
gradle build connectedCheck
command to build your project, perform lint checks, and execute your UI tests, which means you need to launch an emulator first after downloading it, running it, and waiting for it. There is a ready Travis script, but it is still unreliable. So let’s add this line:
script: - ./gradlew build check
It will override the default command, and Travis will only run lint and emulator independent unit-tests (I suggest you keep your gradlew with the source code as recommended). Now we are ready to go! Here is the full minimal working .tavis.yml file for you:
language: android jdk: oraclejdk8 env: global: - ANDROID_API_LEVEL=25 - ANDROID_BUILD_TOOLS_VERSION=25.0.2 android: licenses: - 'android-sdk-preview-license-.+' - 'android-sdk-license-.+' - 'google-gdk-license-.+' components: - tools - platform-tools # The BuildTools version used by your project - build-tools-$ANDROID_BUILD_TOOLS_VERSION # The SDK version used to compile your project - android-$ANDROID_API_LEVEL # Additional components - extra-google-google_play_services - extra-google-m2repository - extra-android-m2repository - addon-google_apis-google-$ANDROID_API_LEVEL before_script: # Prepare pre-accepted licenses to not be promted at installation - mkdir -p "$ANDROID_HOME/licenses" - cp ./google-licenses/* "$ANDROID_HOME/licenses/" script: - ./gradlew build check
If you have no specific dependencies, you can omit before_script section, and if you’re brave enough to play with the emulator, you may want to add something like this
to the components and this
# Launch emulator before the execution - echo no | android create avd --force -n test -t android-25 --abi google_apis/armeabi-v7a - emulator -avd test -no-audio -no-window & - android-wait-for-emulator - adb shell input keyevent 82 &
to the before_script. Note that the create avd command uses different notation and that you cannot copy-paste the component name to it –
-t android-25 --abi google_apis/armeabi-v7a
Basically, you specify the Android version as the separated -t parameter, abi version as the –abi parameter, and additional parts such as Android Wear or Google API are listed as the abi prefix like google_apis/. The full list is available via the same command:
android list sdk --extended --no-ui --all
Enjoy your painless CI! If you want help setting up your Travis or any other continuous integration tool, our DevOps team will be happy to help.