Let’s start — create the keystore

Our first step is to create our Keystore file. The easiest way is to follow the official Generate Key and Keystore guide. If you already have a Keystore and credentials, great — skip this part. The important thing to remember here is to not actually use the wizard to sign your app — once you’ve created the keystore and assigned credentials to it, you should click cancel. Remember the credentials you used as you’ll need them shortly.

This means you’ve created the keystore. You can cancel at this stage.

Store our keystore securely with Travis

We have our keystore, great. Now we have to add it to Travis. For this we’ll use the Travis File Encryption functionality. If you’ve not done so already, install the Travis command line tools by executing gem install travis in your terminal. Use the terminal to cd into your project location. Execute travis login to make sure you authenticate Travis with your Github account.

Now, copy the your keystore file to the place in your project repository you’d like it to live. I just put it in the root repo folder for this example. Now run the following command travis encrypt-file OurStore.keystore --add replacing OurStore.keystore with your own Keystore name. You’ll see something like the following output.

Before you do anything else, delete the original keystore file from the repository folder where you executed the command (as Travis handily informs you to). Now you’re left with something called OurStore.keystore.enc — this is the encrypted version of the file and can be safely commited to your repository. You’ll also notice the following command in the before_install step of your .travis.yml file:

before_install: - openssl aes-256-cbc -K $encrypted_839e38d787bc_key -iv $encrypted_839e38d787bc_iv -in OurStore.keystore.enc -out OurStore.keystore -d

I won’t go into how openssl works here, but simply put what has happened is that Travis has encrypted our file using the aes-256-cbc cipher, which is an industry standard encryption algorithm. The arguments it passes as -K and -iv are the key and initialisation vector, respectively (google that if you want to learn more about it). Travis generates those and, if you look in your Travis web console project settings page, you’ll see that those two parameters have been added to the Environment Variables list. Notice that even we can’t see those values. They’re secret and only available to the Travis Virtual Machine when it works on your app.

What you actually care about is that this command runs in the before_install step and it decrypts the .keystore.enc file to provide us with what we need — our .keystore file. Similar to the Environment Variables, our keystore will only be available on the Travis VM while it builds on our app. Since Travis will tear down the VM after it finishes, we can be sure it won’t be leaked anywhere else.

Great — so now when Travis builds our app we will have access to our Keystore. On with the next step.

Store our credentials securely with Travis

Getting access to our Keystore is only half the work — we still need our credentials for it in order to create a signed APK. Doing this is very simple — we’ll just use the Environment Variables — the place that Travis stored our Keystore decryption parameters — to also store our credentials.

The reason why we use Environment Variables is twofold — first, they are encrypted and second — they are available to our whole project, which is useful if you want to generate APKs from different branches.

Go to the Travis web console settings page and add your parameters. Remember, don’t enable the Display Value in build log option else they will be printed to build logs which is not safe. Name them something sensible — you can see how they are named in the example here:

Now, keystore_alias, keystore_alias_password and keystore_password will be available as system environment variables when the Travis VM builds the app. Now its time to jump into our gradle file to tie this all together.

Create and sign a release version of the apk

Time to edit the app’s build.gradle file. There we need to create a release signing config and populate it — but only when running on Travis, since we won’t have access to the data otherwise. You can see how to handle that below.

Modified file to setup a signing config when running on Travis

You can see the important bits are in the lower half of the file. We use the System.getenv function to get access to the environment variables Travis provides. "CI" is actually one of the default handy variables Travis sets for us. We use it here to determine whether Travis is building our app. If that is the case we populate our signing config with the store file, password, key alias and alias password. Pretty straightforward!

One final step — let’s deploy to Github Releases

Creating a signed APK is not much use unless we actually deploy it somewhere. You can find the guide on how to setup Github releases with Travis here. When setting up the example project used for this article the .travis.yml file ended up like this:

It’s a very simple implementation — it will deploy to Github releases when a commit is tagged in the repo. The deployment will contain the contents of the apk release folder.