Fastlane is a build automation tool for both iOS and Android developed by Felix Krause. Its tooling provides the ability to automate screenshots, run tests, manage code-signing, distribute beta builds, publish applications, and so much more. Needless to say, it is a toolset that any mobile developer should become familiar with. In this blog post, I am going to talk about how I use Fastlane and TravisCI in one of my upcoming projects.


I am going to assume that you are already familiar with TravisCI and know how to configure it to automatically build your iOS project.

How it works

Fastlane allows you to configure workflows that you would like to automate. These workflows are called lanes and are defined as a script called the Fastfile. The lanes are run by calling fastlane {name of the lane} from the command line in the directory of the project. For example, fastlane beta.

My Fastfile

Here is a snippet of my Fastfile so that you can get a general idea of how I configured my workflows. For those who wish to view the entirety of the Fastfile, I have published it as a gist.


platform :ios do

  desc "Run Unit and UI Tests"
  lane :test do
    # Install Pods
    cocoapods(clean: true, repo_update: true )
    run_tests(workspace: "Tempo.xcworkspace",
		 devices: ["iPhone 6s"],
		 scheme: "Tempo",
		 slack_channel: "#general")
    # Compute the code coverage
    slather(cobertura_xml: true,
		scheme: "Tempo",
		simple_output: true,
		travis_pro: true,
		workspace: "Tempo.xcworkspace"
    # Report Coverage to
    codecov_reporter(token: "$CODECOV_TOKEN")

  desc "Push a new beta build to TestFlight"
  lane :beta do
    # Increment the build number (not the version number)
    build_number = increment_build_number(xcodeproj: "Tempo.xcodeproj")
    # Commit the version bump, skipping CI Build
    commit_version_bump(xcodeproj: "Tempo.xcodeproj",
      message:"[ci skip] Version Bump to #{build_number}")
    # Push new build number
      remote: "origin",         # optional, default: "origin"
      remote_branch: "develop", # optional, default is set to local_branch
      tags: false     # optional, default: true
    cocoapods(clean: true, repo_update: true)
    sync_code_signing(type: "appstore")
    upload_to_testflight( demo_account_required: true, groups: "Tempo Testers",
      distribute_external: true, changelog: "Here is what's new with Tempo:" )
    slack(message: "Successfully distributed a new beta build")

Getting Fancy with TravisCI

I created the following shell script that uses the TravisCI environment variables in order to determine which lane to run:

#! /bin/sh

if [[ $TRAVIS_COMMIT_MESSAGE == *"[fastlane deploy beta]"* ]]; then
  bundle exec fastlane beta
  exit $?
elif [[ $TRAVIS_COMMIT_MESSAGE == *"[fastlane deploy release]"* ]]; then
  bundle exec fastlane release
  exit $?
elif [[ $TRAVIS_COMMIT_MESSAGE == *"[fastlane capture screenshots]"*  ]]; then
  bundle exec fastlane screenshots
  exit $?
elif [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then
    bundle exec fastlane test
    exit $?
  bundle exec fastlane test
  exit $?

Basically what is going on here is that I tell the TravisCI build system to check the commit message for a command that I define in the git commit message; such as [fastlane deploy beta]. This allows me the flexibility of being able to dynamically select a workflow for each git commit, and then run it on a remote continuous integration server. Running Fastlane on TravisCI takes build automation to the next level. You won’t have to wait by your computer or keep it from sleeping to complete a build. You can take a break because you’ll receive a notification from the TravisCI when the build completes.


You may notice that I list a command .fastlane/ This script simply sets the git properties --global and --global I do this to allow TravisCI to push version bumps to my repo, however it is not required if you do not want to push in your workflow.

Configuring the Shell Script to run on TravisCI

Getting TravisCI to run the shell script is actually very straightforward. I call from the .travis.yml as so:


os: osx
osx_image: xcode9
language: objective-c
- bundle install
- ./fastlane/

That’s It!

That is all it takes to configure TravisCI to dynamically run Fastlane workflows. I hope you found this post useful and I recommend you try it with your iOS Projects.