TravisCI & CircleCI 2.0 with Fastlane for React Native(both iOS and Android)
Let’s automate build and deployment process for your react native(iOS, Android) project!
In this post, I will show you how to integrate your existing Fastlane script(supposed that you have already set up with Fastlane) with TravisCI and CircleCI 2.0. I will not explain what Continuous Integration is or why you should use CI since there are a lot of good articles to explain.
I am going to focus on how to setup.
If you haven’t set up your RN project with Fastlane, you can refer my previous post(React Native with Fastlane and Crashlytics Beta)
It’s always annoying to configure tools for build environment but once you have configured, it makes you life easier and more focus on coding :)
TravisCI
- Android
1. Encrypt keystore file
When you deploy an android app, you need to sign your app with keystore. Let’s upload a keystore file to your source control but make sure you way want to encrypt keystore file.
If you haven’t generate keystore file, otherwise you can skip this part
In project root$> keytool -genkey -v -keystore rn-sample-key.keystore -alias rn-sample-key-alias -keyalg RSA -keysize 2048 -validity 10000$> mv rn-sample-key.keystore ./android/app
Let’s encrypt keystore file
In project root$> travis login --auto$> travis encrypt-file ./android/app/rn-sample-key.keystore$> mv rn-sample-key.keystore.enc ./android/app
You can see something like this as below
You don’t want to “-- add” option since keystore file needs to be located at ./android/app. You may add the script with openssl as instructed
2. Add Environment Variables in Travis setting
Let’s assume that your ‘~/.gradle/gradle.properties’ looks like this as below
RNSAMPLE_RELEASE_STORE_FILE=rn-sample-key.keystoreRNSAMPLE_RELEASE_KEY_ALIAS=rn-sample-key-aliasRNSAMPLE_RELEASE_STORE_PASSWORD=rn-sample-keyRNSAMPLE_RELEASE_KEY_PASSWORD=rn-sample-key
In travis setting, you can add environment variable as below
Please make sure to match buildToolsVersion on 'build.gradle' and '.travis.xml'
3. modify your ‘app/build.gradle’ and ‘Fastfile’
4. Finally you can write a script like below
- iOS
- Matchfile
2. Add Environment Variables in Travis setting
* FASTLANE_USER => ‘{{ apple developer portal id }}’* FASTLANE_PASSWORD => ‘{{ password for apple developer portal id }}’* MATCH_PASSWORD => ‘{{ passphrase for Git Repo }}’ : match repository password* MATCH_KEYCHAIN_NAME => ‘{{ ***.keychain }}’ ex) ios-build.keychain * MATCH_KEYCHAIN_PASSWORD => ‘{{ any_password for keychain }}’
3. Add Deploy key and setup for private certificate repository
You may generate a ssh key to certificate repository’s ‘Deploy keys’ setting by referring two links below.
Make sure to add ‘.deploy_key.enc’(encrypted deploy key for Travis to access certificates) and ‘.deploy_key.pub’ to your git repository
Let’s encrypt deploy_key just like you did for keystore of android above
$> travis login --auto$> travis encrypt-file .deploy_key.enc
Later you may add this script to ‘.travis.xml’
- openssl aes-256-cbc -K $encrypted_5a0bd94d6bee_key -iv $encrypted_5a0bd94d6bee_iv -in .deploy_key.enc -out ~/.ssh/deploy_key -d- echo -e "Host github.com\n\tHostName github.com\n\tUser git\n\tIdentityFile ~/.ssh/deploy_key\n" >> ~/.ssh/config- ssh-keyscan github.com >> ~/.ssh/known_hosts- chmod 600 ~/.ssh/deploy_key
In this script, it decrypts deploy key(encrypted) with ‘openssl’ just like how you did with keystore file for android above, and it adds github host to ~/.ssh/config and ~/.ssh/known_hosts then gives permission otherwise you would see warning as below
References for this
- https://github.com/openmicroscopy/devspace/issues/38
- Fixing “WARNING: UNPROTECTED PRIVATE KEY FILE!” on Linux
4. Setup for keychain
When it code sign your app in your macOS, you normally see this prompt UI
In TravisCI, you need to generate custom keychain to manage this by adding this to Fastfile
It creates a new keychain. Otherwise, MacOS would display an interactive prompt during the build phase which freezes the build indefinitely. and it invokes match
to fetch a certificate into a newly created keychain. The match
is invoked in a read-only mode so that it can't mess up the certificates repo. The reason to unlock keychain is that it prevents generating multiple keychains which makes increasing build times (https://github.com/fastlane/fastlane/issues/7505#issuecomment-267445102)
Finally you may see output like this below. You can checkout that Keychains have generated.
5. Finally you can write a script like below
CircleCI 2.0
The CircleCI commands enable you to reproduce the CircleCI environment locally and run jobs as if they were running on the hosted application for more efficient debugging and configuration in the initial setup phase
- We will try run job on your local MacOS for android build
- Installing the CircleCI Local CLI on macOS
- Write a script as below
: You don’t need to pull source code from your repository or install node modules since it duplicates your local environment to circleci environment(installed docker in your machine)
Make sure to comment out location to sdk.dir in ‘local.properties’ since it duplicates your local environment
# sdk.dir=/Users/tjkang/Library/Android/sdk
Let’s run a script
$> circleci build --job android -c config.local.yml
You can also get keystore file from external source like dropbox not from repository if you don’t want to manage a release-keystore in source repository.
Lets assume that there are ‘gradle.properties’ and ‘keystore’ files uploaded in dropbox
2. Sample parallel workflow config for both iOS and Android with caching
Make sure that you need to create custom keychain for iOS code signing, otherwise it would occur error like this below
▸ Signing /Users/travis/Library/Developer/Xcode/DerivedData/PresenterKit-ggzwtlifkopsnbffbqrmtydtmafv/Build/Intermediates/CodeCoverage/Products/Debug-iphonesimulator/project.xctest
No output has been received in the last 10m0s, this potentially indicates a stalled build or something wrong with the build itself.
Check the details on how to adjust your build configuration on: https://docs.travis-ci.com/user/common-build-problems/#Build-times-out-because-no-output-was-received
The build has been terminated
In Fastfile, it should look something like this below and add environment variable for MATCH_KEYCHAIN_NAME and MATCH_KEYCHAIN_PASSWORD from Project settings(Build Settings => Environment Variables) in CircleCI WebConsole.
You can refer “4. Setup for keychain” in TravisCI section above for details
References
- Build a signed meteor android app on Travis CI and push it to GitHub releases
- Travis CI Android example
- Simplifying Android app distribution with Beta by Crashlytics
- Beta Testing React Native Android Applications with Crashlytics
- Android Continuous Integration with Travis CI + Fabric Beta
- Automate Testing & Build Delivery with fastlane and Travis CI
- Continuous delivery with Travis and fastlane
- iOS + Fastlane + TravisCI
- Xcode 8 and automatic code signing
- The simplest way to automate delivery of your React Native Application