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.

Note:

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.

default_platform(:ios)

platform :ios do
  setup_travis

  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.io
    codecov_reporter(token: "$CODECOV_TOKEN")
    end

  desc "Push a new beta build to TestFlight"
  lane :beta do
    test
    ensure_git_status_clean
    # 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
    push_to_git_remote(
      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")
    build_app
    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")
  end
end

Getting Fancy with TravisCI

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

travis.sh

#! /bin/sh

if [[ $TRAVIS_COMMIT_MESSAGE == *"[fastlane deploy beta]"* ]]; then
  ./fastlane/setupGit.sh
  bundle exec fastlane beta
  exit $?
elif [[ $TRAVIS_COMMIT_MESSAGE == *"[fastlane deploy release]"* ]]; then
  ./fastlane/setupGit.sh
  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 $?
else
  bundle exec fastlane test
  exit $?
fi

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.

Note:

You may notice that I list a command .fastlane/setupGit.sh. This script simply sets the git properties --global user.email and --global user.name. 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 travis.sh from the .travis.yml as so:

travis.yml

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

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.