Android Travis CI with Autodeploy (API 26+)

Gerard Rovira
6 min readNov 2, 2017

--

[Example repository]

Hello there!

Given that setting up Travis to work with Android is such a pain[1][2][3][4], I thought I could share my little knowledge to newcomers after having spent a day digging through tutorials to get my project working. This article is meant to be a more complete version of my StackOverflow reply.

One of the users who I’ve come across the most when looking up for information was Sean Barbeau, who pretty much considered it impossible to emulate as it was done in the past.

Prior API 24, it did work by installing the proper Android Emulators. For those who’s not in their interest to update to the latest API versions, I suggest you to read Travis CI Android Example and How to Deploy APK to GitHub releases with Travis CI. They are both excellent articles.

I assume that you know at least the very basics of Travis CI, such as how to enable it. Otherwise you might want to head over the Getting Started tutorial first.

Let’s start. What’s the problem?

— API 24+ Android emulators do not work with Travis CI (this should be an OK configuration).

An acceptable solution seems to be using gradlew to run the application tests instead of adb emulator. It seems to have some limitation, but it should work. Credits to PocketHub.

Automatic tests

Having said that we have to use gradlew , let’s see how the solution actually looks like for running the application tests only.

Let’s see how it can be done.

Relevant stuff:

  • before_cache and cache is optional, but it will speed up our runs by reusing previously downloaded dependencies. Recommended by Travis on their documentation.
  • env your application API numbers go here. We’ll get into that in a second¹.
  • components Android must-have requirements on the system.
  • script What we want to evaluate. In this case we want Travis to run our tests and also make sure that the application can be built correctly. We will later use the built application as our release artifact.

¹Environment variables that you might have to adapt to your project ones:

Some information should be available either in the build.gradle or AndroidStudio -> Settings -> Android SDK -> SDK Tools

(if you’re building a new project with an updated AndroidStudio you should just pick the latest versions in the following links)

ANDROID_API: https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels

ANDROID_BUILD_TOOLS: https://developer.android.com/studio/releases/build-tools.html

Automatic tests + deployment to GitHub Releases

Deployment can be done anywhere once we have the artifact ready (that is the APK that we want to publish). For most cases, the most cumbersome process is the generation of the signed APK. Later, you can adapt it to deploy it to somewhere else by following a similar strategy.

What we want to do now is: have our latest master version deploy as a latest release. Generating a different one per commit once we have this set up is trivial, but I believe that this would lead to an insane amount of releases (which we would probably prefer to cherry-pick by ourselves instead).

Let’s see the resulting .travis.yml file:

First thing you will notice is that we now have three more environment variables (the x3 secure).

These are the (1) keystore password, (2) key password and (3) GitHub API keys encrypted.

(1) and (2). AndroidStudio -> Build -> Generate Signed APK -> Create new

The keystore path should be the root folder of your project (I named it keystore.jks).

First password is the keystore password, second one is the key password. Note them down.

To obtain a encrypted version, run travis encrypt storepass=password_here and travis encrypt keypass=password_here .

(3). GitHub New Token. Check repo (full control of private repositories)

Encrypt that as well travis encrypt GH_TOKEN=token_here . We’ll be reusing that token later. Don’t lose it.

For the before_deploy part, we’ll need a encrypted version of keystore.jks. You must not upload that on GitHub.

travis encrypt-file keystore.jks

If you are not logged in to Travis it will promp not logged in — try running travis login --org. You can reuse the GitHub token we generated before to do so.

travis login --github-token your_token_here

We will still need this token one more time.

It should generate a keystore.jks.enc which is the encrypted version. You have to upload this one. Make sure to add keystore.jks to your .gitignore or move that file away from that folder now.

It should also return you a line of code like the following: openssl aes-256-cbc -K ... Replace the first before_deploy line with this one.

For your information, what we do next is to sign the built APK (from the scripts part) with the keystore information we just generated. It then verifies it, and zipaligns it (which is pretty much about optimizing it for production use).

You might have to change the alias name on the first jarsigner command line (that is the last parameter). To find out your the alias you set earlier you can use the following command:

keytool -keystore keystore.jks -list -v

Now, you have to copy-paste the following file into scripts/tag.sh

Give it execution permissions: chmod +x scripts/tag.sh

What we do here is to create a tag to the latest commit on the master branch history. We’re basically saying that the latest commit hash is aliased to the latest name, which will make it appear on the releases GitHub tab.

Since we are reusing the latest name in every build, we have to delete and recreate the tag every time to have the time updated.

Note that we are not updating any artifact in here, we are simply mapping a commit hash with a name.

Lastly, going back to the .travis.yml file, we have the deploy part.

This one is the responsible for uploading the signed APK we generated earlier.

Since the deploy is already handled by Travis, we just need to pass it in a GitHub API Key (encrypted of course). In this step you might want to reuse the API key we created last in here.

Encrypt it like this travis encrypt token_here . Note that this time we don’t have GH_TOKEN environment variable name in front.

The result of which has to be written in the secure part of the deploy.

Two relevant flags to notice:

overwrite : since the latest tag will be reused, we want the APK to be rewritten every time.

skip_cleanup : we don’t want artifacts to be removed before deploying.

And that’s it! You should now have Travis autodeploying your Android project.

Automatic tests + deployment to somewhere else

Since there are endless possibilities, I won’t go in depth with this.

If you’ve fully read the previous deployment to GitHub Releases instructions, you will notice that you may just have to change the deploy part of the .travis.yml , and maybe remove the scripts/tag.sh line and file.

Signing the APK has to be done either way if you want your APK to be delivered to someone else but the development team.

You can check the example repository here.

Have any questions? Please, let me know in the comments.

You can also get in touch with me via Twitter, LinkedIn, GitHub, StackOverflowor Mail.

Mail: bWFpbHRvOnp1cmZ5eEBnbWFpbC5jb20=

--

--

Gerard Rovira

Full stack developer. JavaScript, TypeScript, React, Angular, Node @_zurfyx