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.
There are some things you'll need before we get started.
Ask a senior engineer for help with a couple things:
Ask the client to add you to their Apple Developer Account as an Admin.
- Once you have access, add
firstname.lastname@example.org, 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.
- Once you have access, add
bundle installin the root of your repo. This will install
fastlaneand related gems.
Gemfile.lockif it was changed by bundler.
If you don't already have the
travisgem installed, do so now by running
sudo gem install travis.
All Fastlane config files are in 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_ignorearray, further down in the file.
- No other changes to this file should be necessary.
Appfile. This file provides details about the app as it exists in the Apple ecosystem.
apple_dev_portal_idshould normally be set to
email@example.com. 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.
Matchfile. This file provides configuration for
match, which is the Fastlane tool responsible for managing signing certificates.
- Make sure the
git_branchis set to the name of the client, not necessarily the name of the project.
- Make sure 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).
FIXMEvalues with the appropriate values, where you can. You'll probably need to come back to this later on.
FASTLANE_PASSWORDto your own Apple ID credentials. These will be used by
matchin 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.shfirst, using the
.command, to set environment variables. You must also use
bundle execto ensure that the correct version of
fastlaneand 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
matchcommands. 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
That should do it!
Review the contents of
- Change any values that are incorrect.
- Set items that still have a
- 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
addonssection at the bottom of
Generate a Personal Access Token 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.ymlfile. For each variable in that section, run the
travis encryptcommand from the root of your repo:
travis encrypt 'VARIABLE_NAME=TheValueToEncrypt' -r vokal/YourRepoName
VARIABLE_NAMEwith the name of the variable to set,
TheValueToEncryptwith the value to assign to the variable, and
YourRepoNamewith the name of your repo. This will print out a line like this:
Copy this output, and use it to replace the line in
.travis.ymlwhere 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.ymlfile 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 the
travisgem. If that is not possible, make sure to
\-escape your those characters when entering the password into the shell.
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
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
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
FASTLANE_PASSWORD, using the process described previously, and drop it into your
- If you used a different Apple ID for
Appfile, encrypt the password for that account here instead.
- If you used a different Apple ID for
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
To upload to HockeyApp, you need to generate an upload token.
Account Settings, select
API Tokensin the left sidebar, and generate a new Upload Only token for your app.
Add this token to your
HOCKEY_API_TOKEN, then encrypt it as a
secureenvironment variable with the same name in
Once this variable is added, Fastlane will be able to run the
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.
firstname.lastname@example.org iTunes Connect as a Developer.
Have a senior engineer encrypt the password as
.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
ITC_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.ymlfile at the root, with the contents of the file in the project template.
- Add a
notificationssection 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:
travisdirectory: replace the existing one in the project, if it's there. Keep any custom scripts that may have been put there previously.
.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.
.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
.gitignoreto include everything listed in the project template version
- Review your Build Phases and replace Run Script phases with calls to scripts in the
Scriptsdirectory, where appropriate
- Make use of the
USE_PRODUCTION_SERVERuser-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 for
USE_PRODUCTION_SERVERto see how the flag should be used.
Finally, go back to the top of this document and follow the instructions.