Fastlane & Travis CI
Fastlane is a command-line tool used to automate a lot of tasks (building projects, running tests, distributing builds) with the help of a suite of sub-tools.
Travis CI is a continuous integration service used to build and test software projects hosted at GitHub. For every pull request in our repos, Travis will locally make the proposed merge, then use Fastlane to build the project and run its tests, then uploads test coverage details to CVR. When a pull request is merged, Travis can also send builds to HockeyApp or iTunes Connect automatically (again, with the help of Fastlane).
This document includes instructions for configuring both on new projects. If you're adding this functionality to an existing project, see the Switching to fastlane section at the bottom for some details.
Prerequisites
There are some things you'll need before we get started.
- Ask a senior engineer for help with a couple things:
- Enable the repository in our Travis CI account. If you are having trouble locating your new repo from the list of repos on the Travis interface, try hard coding the URL path
https://travis-ci.com/vokal/YourRepoName
to take you to the correct page. - Generate a secure key/secret using s3same for our Amazon S3 bucket. You'll need the output from this in a later step.
- The password used to encrypt signing certificates in the certificates repo.
- Ask the client to add you to their Apple Developer Account as an Admin.
- Once you have access, add
build@vokal.io
, too. Your Director should have access to this email address to accept requests to join teams. This will allow us to generate and download a signing certificate and provisioning profiles as needed, and ensure that other devs can get access if they join the project. - Make sure the App ID has been created for the app.
-
Run
bundle install
in the root of your repo. This will installfastlane
and related gems. -
Commit
Gemfile.lock
if it was changed by bundler. -
If you don't already have the
travis
gem installed, do so now by runningsudo gem install travis
.
Fastlane Configuration
All Fastlane config files are in the fastlane
directory.
- Review the
Fastfile
. This contains the "lanes" used by Fastlane to actually perform various build tasks.
- Check the values in the Variables each project must update section update the file and scheme names if necessary.
- If you're updating a project that wasn't created from our project template, you'll need to correct the paths for files in the
coverage_files_to_ignore
array, further down in the file. - No other changes to this file should be necessary.
- Review the
Appfile
. This file provides details about the app as it exists in the Apple ecosystem.
apple_dev_portal_id
should normally be set tobuild@vokal.io
. If this Apple ID was not added to the client's developer team, as noted in the Prerequisites section, then this needs to be set to some other account that is on the team.- Update the other values as appropriate.
- Review the
Matchfile
. This file provides configuration formatch
, which is the Fastlane tool responsible for managing signing certificates.
- Make sure the
git_branch
is set to the name of the client, not necessarily the name of the project.
- Review the
local_config.sh
. This file sets environment variables that normally contain passwords and access keys. When Fastlane is run on Travis, these values come from encrypted values in.travis.yml
(we'll do that in a later step).
- Replace
FIXME
values with the appropriate values, where you can. You'll probably need to come back to this later on. - Set
MATCH_USERNAME
andFASTLANE_PASSWORD
to your own Apple ID credentials. These will be used bymatch
in the last step below to generate signing certs and provisioning profiles. - NEVER COMMIT THIS FILE.
-
Try running a lane to confirm the basic configuration is correct. When running Fastlane locally, be sure to load the contents of
local_config.sh
first, using the.
command, to set environment variables. You must also usebundle exec
to ensure that the correct version offastlane
and other tools (specified in the Gemfile) are used:. ./fastlane/local_config.sh bundle exec fastlane ios test
-
Setup the signing certificates and provisioning profiles for the app by running the following
match
commands. You may be prompted for the password used to encrypt the certificates repo and your Apple account password, if they're not already in your keychain.bundle exec fastlane match appstore bundle exec fastlane match adhoc bundle exec fastlane match development
-
Once the certs and profiles have been generated, go into the Xcode general build settings tab for the main target. Then select the appropriate "Signing (Debug)" and "Signing (Release)" provisioning profile dropdown values and commit.
That should do it!
Travis Setup
- Review the contents of
.travis.yml
:
- Change any values that are incorrect.
- Set items that still have a
FIXME
placeholder. - Don't touch anything under the Secure environment variables section comment yet.
-
Paste the encrypted S3 credentials from the senior engineer (from the Prerequisites section) into the
addons
section at the bottom of.travis.yml
. -
Generate a Personal Access Token with
repo
scope on GitHub. This will be used to authenticate with Travis. -
Log in to the travis command line tool. Run
travis login --pro --github-token [token]
, replacing[token]
with the one you generated in the previous step. -
Encrypt the "secure" properties in the Secure environment variables section of the
.travis.yml
file. For each variable in that section, run thetravis encrypt
command from the root of your repo:travis encrypt 'VARIABLE_NAME=TheValueToEncrypt' -r vokal/YourRepoName
Replace VARIABLE_NAME
with the name of the variable to set, TheValueToEncrypt
with the value to assign to the variable, and YourRepoName
with the name of your repo. This will print out a line like this:
```yaml
secure: "MUMOHFGS1M23fGy3crZ5/RIINdmFetHRnnLvrUsPhkJ3/J4acPRM+9TyLaJImmInOo4sz4Y9/p38a7Xvp0GP0RV7wLqhtdsawKXPd1wmD6IIkx8PCvhA2HH1O3PxcKs8NYH5SQWflSperQ+s+LMV4ePFbPBkO3JpKtsKP/gllYk="
```
Copy this output, and use it to replace the line in .travis.yml
where the variable had previously been set to FIXME
. Make sure it's still prefixed with a -
, and that the variable you encrypted is the one mentioned in the comment above the spot where you paste it.
A few notes on secure variables:
- The use of
vokal/
rather than your personal GitHub username is intentional. Encryption of secure properties in the.travis.yml
file is tied to an SSL certificate that is fork-specific. - Secure variables are only available to Travis once a PR has been merged. This prevents arbitrary code being PR'd from causing things like uploads to HockeyApp or iTunes Connect, or disclosing these secure values to people who shouldn't have them.
- Avoid using shell-special characters like
/
,&
, or parentheses if possible in the values being encrypted by thetravis
gem. If that is not possible, make sure to\
-escape your those characters when entering the password into the shell.
Distribution Channels
Fastlane is used to upload builds to Hockey and/or iTunes Connect (for TestFlight and App Store). This can be done locally from your machine, but we typically have Travis do so on merge builds (which happen when a pull request is merged) so that builds are automatically available in HockeyApp to be sent out to product owners and other testers.
Note that the distribute.sh
script (which is run by Travis on merge builds) bails out if either HOCKEY_API_TOKEN
or ITC_PASSWORD
is still set to "FIXME". If you only want to have builds automatically uploaded to one of these services, make sure you comment out the other in .travis.yml
.
Signing
All builds must be signed using a Distribution certificate and the appropriate provisioning profile so that they may be installed by non-developers.
Fastlane's sigh and match utilities facilitate signing by using provided credentials to log in to the Apple Developer Center and grab provisioning profiles and certificates, respectively, for signing your builds.
Most of this is automated. You only have to set one variable, if you haven't already:
- Ask the director to encrypt the Apple ID password for
build@vokal.io
as asecure
variable calledFASTLANE_PASSWORD
, using the process described previously, and drop it into your.travis.yml
.
- If you used a different Apple ID for
apple_dev_portal_id
in theAppfile
, encrypt the password for that account here instead.
Lanes for distributing via HockeyApp and iTunes Connect will provide the necessary information to the archive_build
private lane, which calls gym to build and sign an .ipa
.
HockeyApp
To upload to HockeyApp, you need to generate an upload token.
-
Go to
Account Settings
, selectAPI Tokens
in the left sidebar, and generate a new Upload Only token for your app. -
Add this token to your
local_config.sh
asHOCKEY_API_TOKEN
, then encrypt it as asecure
environment variable with the same name in.travis.yml
.
Once this variable is added, Fastlane will be able to run the hockey_staging
and hockey_prod
lanes, uploading staging or production builds to HockeyApp.
If you get an SSL error locally when deploying to HockeyApp, see the fastlane FAQs.
iTunes Connect
-
Invite
build@vokal.io
to iTunes Connect as a Developer. -
Have a senior engineer encrypt the password as
ITC_PASSWORD
for your.travis.yml
. -
Add
build@vokal.io
as theITC_USERNAME
in your.travis.yml
. This one doesn't need to be encrypted. -
If you'd like to upload builds to iTunes Connect from your machine, put your own account credentials in
local_config.sh
asITC_USERNAME
andITC_PASSWORD
. Once you do, you can upload builds by running:. ./fastlane/local_config.sh bundle exec fastlane ios itc
NOTE: Steps 1-3 are only needed if you want to automatically upload builds to iTunes Connect after every successful Travis merge build. If you only want to manually upload builds to iTunes Connect from your machine on an on-demand basis using Fastlane, then only step 4 is needed.
NOTE: Once a build is uploaded to iTunes Connect, it cannot be deleted, and it also cannot have a build with a lower short version number uploaded. Be accordingly careful when testing this functionality.
Build Wall and Drone
The build walls around the office are based on statuses from Drone, which is the build server that's used by other engineering disciplines. Since our builds run on Travis, we have sort of a bridge build that also runs on Drone and waits for a notification from Travis that the build has finished, so that it can be displayed on our build walls.
To show the Travis build status on our build walls, activate the repo from the repo list on our Drone server (a senior dev can grant you access if you need it). If you created the project from our project template, that's all you need to do.
If you created a project from scratch, or inherited one that wasn't created from our template, you just need to make two more adjustments to your project.
- Add a
.drone.yml
file at the root, with the contents of the file in the project template. - Add a
notifications
section to your.travis.yml
, again matching the contents of the file from the project template.
Switching to fastlane
We started using fastlane in early 2016, and projects before that mostly used custom scripts for Travis. If you're updating one of those projects to use fastlane, it's probably best to just start from scratch: our build flow has evolved a lot since adopting fastlane (and some variable names changed, like HOCKEY_API_TOKEN
), so attempting to update the existing Travis config in the project is likely to be a pain. Just replace it and move on.
Start by copying some things from our Xcode project template to make sure you've got the latest scripts and templates for config files. From the base template directory, you'll need:
- The
fastlane
directory - The
travis
directory: replace the existing one in the project, if it's there. Keep any custom scripts that may have been put there previously. .drone.yml
.travis.yml
: replace the existing one, but you might want to keep the old one handy for a bit in case you need to copy over any values into the new one.Gemfile
.gitignore
: merge this with the version already in the project
There are some changes you might need to make to the project itself:
- Remove the ad-hoc configuration and scheme
- Set the provisioning profiles to Automatic in the build settings, for all configurations
- Change your main scheme to use the Release configuration for the Archive action
- Main scheme should test both UI and Unit test targets
- Update your
.gitignore
to include everything listed in the project template version - Review your Build Phases and replace Run Script phases with calls to scripts in the
Scripts
directory, where appropriate - Make use of the
USE_PRODUCTION_SERVER
user-defined build setting, to toggle between staging and production API servers. This includes multiple steps. The easiest way to add this is to create a new project using our template and include the starter network utility. Then, search this dummy project forUSE_PRODUCTION_SERVER
to see how the flag should be used.
Finally, go back to the top of this document and follow the instructions.