Document toolboxDocument toolbox

Android CI Setup

Overview

This is documentation on how the Android continuous integration is setup.  The purpose of this is to keep a record of our specific setup and as a guide to debugging problems when things are broken.  It provides a nice guide to setting up CI for new android projects.  Note that references to secrets can be found in either Lastpass or in the android-certificates repo.


Repositories

These are the repositories that were created during the CI setup.  Travis treats public and private repos differently so both types were created to test builds on Travis.

  • android-certificates - repository that contains all the shared keystore and keys for Sage android projects.
  • CardiorespiratoryFitness-Android - uses certificates from android-certificates repo. 
  • BloodPressureApp - uses certificates from android-certificates repo.
  • sandboxpriv - a private sandbox repository for testing.  Test projects are in branches.  A good project to use as a template is in the dummydroid branch.
  • sandboxpub - a public sandbox repository for testing.


Requirements

These are some of the tools required to setup this CI.  You will need to install these.

  • Fastlane  (install with gem not brew)
  • Travis client
  • Amazon aws client
  • openssl
  • ruby
  • git-crypt


Setup App Keys

The Sage-Bionetworks/android-certificates repo has the keystore and keys for android apps. The files in that repo are encrypted with git-crypt.  You'll need to unlock the repo to be able to access the keystore and keys.  You can unlock it with either your GPG key or with the master KEYFILE.  It is preferable to setup and use your own GPG key, however if you don't have that setup then you can get the KEYFILE from our Lastpass vault, search for "android-certificates".  Look for secrets (KEYSTORE_PASSWORD and KEY_PASSWORD) in the SageBionetworks.secrets file.

Once the repo is unlocked you can use the Java keytool to list the keys:

keytool -list -v -keystore SageBionetworks.keystore -storepass "$KEYSTORE_PASSWORD"


If you are setting up a new app then you should add a key for that app to Sage-Bionetworks.keystore. You can do that in Android Studio or using the keytool.

To add a new key to an existing keystore:

keytool -genkeypair -v -keystore SageBionetworks.keystore -storepass "$KEYSTORE_PASSWORD" -alias $KEY_ALIAS -keypass "$KEY_PASSWORD" -keyalg RSA -sigalg SHA256withRSA -validity 9125

What is your first and last name?
  [Unknown]:  Sage Bionetworks
What is the name of your organizational unit?
  [Unknown]:  Engineering
What is the name of your organization?
  [Unknown]:  Technology Platforms & Services
What is the name of your City or Locality?
  [Unknown]:  Seattle
What is the name of your State or Province?
  [Unknown]:  WA
What is the two-letter country code for this unit?
  [Unknown]:  US
Is CN=Sage Bionetworks, OU=Engineering, O=Technology Platforms & Services, L=Seattle, ST=WA, C=US correct?
  [no]:  yes

Generating 2,048 bit RSA key pair and self-signed certificate (SHA256withRSA) with a validity of 9125 days
	for: CN=Sage Bionetworks, OU=Engineering, O=Technology Platforms & Services, L=Seattle, ST=WA, C=US
[Storing SageBionetworks.keystore]


Now you can use the new key to "Generate a signed Apk" in android studio.  Please enable both "V1 Jar Signature" and "V2 Full Apk Signature" when generating the signed Apk.

Setup Travis

Setting up travis to build and deploy the app to the google play store requires a few steps.

git-crypt

Get the git-crypt.key for android-certificates from our Lastpass account

Travis encrypt the git-crypt.key

travis login --pro
travis encrypt-file git-crypt.key --repo Sage-Bionetworks/BloodPressureApp-Android --api-endpoint https://api.travis-ci.com/

The above command should generate a git-crypt.key.enc file and added a travis environment variables to the travis build settings for that project.

Rename git-crypt.key.enc to something more descriptive, like git-crypt-android-certificates.key.enc

Commit the encrypted key file, git-crypt-android-certificates.key.enc (*NOT* git-crypt.key) to the repo.

Delete the git-crypt.key file.

Travis ENV

Set the following travis build environment variables:

CI_USER_TOKEN (from lastpass) - used to allow cloning the android-certificates repo (private repo) 
KEY_ALIAS (in Sage-Bionetworks.secret) - The app alias
KEY_PASSWORD (in Sage-Bionetworks.secret) - The app alias password
KEYSTORE_PASSWORD (in Sage-Bionetworks.secret) - The keystore password

Travis SSH Key

Part of the deployment process is to commit a tag to the git repo.  In order for travis to do that a SSH key will need to be setup on travis.  I typically just upload the travis user "tcisagebio" ssh key which can be found in lastpass.  Copy/Paste the private key to a "id_travis_rsa" file and do the following:

# from https://github.com/travis-ci/travis-ci/issues/8680
# In your local terminal
> cd path/to/your/local/gitrepo
# login by your account --pro or --org
> travis login --pro
# add the ssh key to travis
> travis sshkey --upload id_travis_rsa --repo Sage-Bionetworks/BloodPressureApp-Android --description travis

Workflow

The general workflow is to create stable branches for releases to google play console.  Master is used as the development branch and stable-x branches are used for releases.  These are  the actions when a PR or commit occurs:

pre-merge (or PRs): build and run tests only

post-merge to master: generate an `enterprise` archive build and deploy to s3 bucket

post-merge to stable-x branch: bump build #, generate an `app-store` archive build, deploy to testflight, commit the new build number to the branch.   The build then may get promoted to the appstore.


Deployment


Before travis can automatically deploy to google play console you must manually add/create the app. You will also need to add the required images for your app and set the privacy policy.  Once you have your app setup on the google play console travis can deploy new builds as updates. 

Debugging

This is a collection of issues I ran into and wanted to keep track of.  This info may help in debugging problems with integration of android studio, fastlane, google play and travis. 

Google Api Error: multiApkDowngradedDevice: Devices with version 4 of this app would be downgraded to version 1 if they met the following criteria: [(API_LEVEL in range 19-0 AND RELEASE_TRACK containing any of each of [[ALPHA]] AND SCREENS containing any of each of [[small, normal, large, xlarge]] AND NATIVE_PLATFORM containing any of each of [[x86, armeabi-v7a, armeabi]] AND FEATURES containing all of [android.hardware.screen.PORTRAIT, android.hardware.FAKETOUCH, android.hardware.LOCATION, android.hardware.CAMERA])].

This indicated that fastlane was attempting to deploy with version 1. In my case, the increment_version_code_plugin was finding versionCode in the comment and incorrectly setting the next versionCode

https://github.com/Sage-Bionetworks/CardiorespiratoryFitness-Android/commit/fc3418f3a111e8c9e9a91ac95a814c790be2e97b

Google Api Error: applicationNotFound: No application was found for the given package name

This error means Google api does not allow the first deployment of the app to google play console.  The workaround is to manually deploy your app then let travis deploy afterwards.  The difference is that travis is updating instead of creating the app on play console. 

References: https://github.com/fastlane/fastlane/issues/10324https://github.com/fastlane/fastlane/issues/3628