New to fastlane? Click here to open the installation & setup instructions first

1) Install the latest Xcode command line tools

xcode-select --install

2) Install fastlane

# Using RubyGems
sudo gem install fastlane -NV

# Alternatively using Homebrew
brew cask install fastlane

3) Navigate to your project and run

fastlane init

More Details

Continuous Integration

Best Practices

Two-step or Two-factor auth

Separate Apple ID for CI

The easiest way to get fastlane running on a CI system is to create a separate Apple ID that doesn't have 2-factor auth enabled, with a long, randomly generated password. Additionally make sure the newly created Apple account has limited access to only the apps and resources it needs.

There are multiple reasons on why this approach is much easier:

  • An Apple ID session is only valid for a certain region, meaning if your CI system is in a different region than your local machine, you'll run into issues
  • An Apple ID session is only valid for up to a month, meaning you'll have to generate a new session every month. Usually you'd only know about it when your build starts failing

There is nothing fastlane can do better in that regard, as these are technical limitations on how App Store Connect sessions are handled.

Creating a separate Apple ID allows you to limit the permission scope, have a randomly generated password, and will make it much easier for you to set up CI using fastlane.

Security code and session

When your Apple account has 2-factor or 2-step auth enabled, you'll be asked to verify your identity by entering a security code. If you already have a trusted device configured for your account, then the code will appear on the device. If you don't have any devices configured, but have trusted a phone number, then the code will be sent to your phone. The resulting session will be stored in ~/.fastlane/spaceship/[email]/cookie. Again, the session should be valid for about one month, however there is no way to test this without actually waiting for over a month.

Use of application specific passwords and spaceauth

Before going through this guide, make sure to read the section above.

If you want to upload builds to TestFlight / App Store Connect from your CI machine, you need to generate an application specific password:

  1. Visit appleid.apple.com/account/manage
  2. Generate a new application specific password
  3. Provide the application specific password using the environment variable FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD

Because your CI machine will not be able to prompt you for your two-step or two-factor auth information, you also need to generate a login session for your CI machine in advance. You can get this by running:

fastlane spaceauth -u user@email.com

This will generate a token you can set using the FASTLANE_SESSION environment variable on your CI system.

Bypass trusted device and use SMS for verification

If you have a trusted device configured, Apple will not send a SMS code to your phone for your Apple account when you try to generate a web session with fastlane. Instead, a code will be displayed on one of your account's trusted devices. This can be problematic if you are trying to authenticate but don't have access to a trusted device. Take the following steps to circumvent the device and use SMS instead:

  • Attempt to generate a web session with fastlane spaceauth -u [email] and wait for security code prompt to appear
  • Open a browser to appleid.apple.com or an address that requires you to login with your Apple ID, and logout of any previous session
  • Login with your Apple ID and request a code be sent to the desired phone when prompted for a security code
  • Use the code sent to phone with fastlane instead of with the browser

Environment variables to set

Most setups will need the following environment variables

  • FASTLANE_USER: Your App Store Connect / Dev Portal user, if your fastlane setup accesses iTC or the DevPortal (e.g. submit a TestFlight build, create a profile, ...)
  • FASTLANE_PASSWORD: Your App Store Connect / Dev Portal password, usually only needed if you also set the FASTLANE_USER variable
  • MATCH_PASSWORD: You need to provide the password of your match encryption if you use match
  • FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: You need to provide an application specific password if you have 2-factor enabled and use pilot or deliver to upload a binary to App Store Connect
  • LANG and LC_ALL: These set up the locale your shell and all the commands you execute run at. fastlane needs these to be set to an UTF-8 locale to work correctly, for example en_US.UTF-8. Many CI systems come with a locale that is unset or set to ASCII by default, so make sure to double-check whether yours is set correctly.

Deploy Strategy

You should not deploy a new App Store update after every commit, since you still have to wait 1-2 days for the review. Instead it is recommended that you use Git Tags, or custom triggers to deploy a new update.

You can set up your own Release job, which is only triggered manually.

Jenkins Integration

Deploying from your own computer isn't cool. You know what's cool? Letting a remote server publish app updates for you.

fastlane automatically generates a JUnit report for you. This allows Continuous Integration systems, like Jenkins, access the results of your deployment.

Installation

The recommended way to install Jenkins is through homebrew:

brew update && brew install jenkins

From now on start Jenkins by running:

jenkins

To store the password in the Keychain of your remote machine, it is recommended that you run match or deliver using ssh or remote desktop at least once.

Ruby Environment

We recommend using rbenv for installing Ruby, though rvm and the version of Ruby that comes bundled on macOS are fine too.

If using a Gemfile in your project, add an "Execute shell" step as your first build step and call bundle update.

Plugins

You'll find the following Jenkins plugins to be useful:

(note: We do not recommend installing the Xcode plugin)

Build Step

Add an "Execute shell" build step using your appropriate fastlane command per the example below:

fastlane appstore

Replace appstore with the lane you want to use.

(note: if using a Gemfile, prefix that command with bundle exec)

setup_jenkins

You can use setup_jenkins action which integrates well with the Keychains and Provisioning Profiles Plugin. Selected keychain will automatically unlocked and the selected code signing identity will be used. Also all build results, like IPA files, archives, dSYMs and result bundles will be stored in the ./output folder in the job workspace. In additions setup_jenkins will create separate derived data folder for each job (in the ./derivedData).

Under the hood setup_jenkins configures other actions like: gym, scan, xcodebuild, backup_xcarchive and clear_derived_data.

commit_version_bump || git_commit

You can use commit_version_bump or git_commit action to commit changes to your repository in your fastlane setup. When you are using webhooks to trigger your build on a push this will cause an infinite loop of triggering builds.

Gitlab

When you are using Gitlab you will need the GitLab Plugin. Inside the job you want to configure you go to Build Triggers > Build when a change is pushed to GitLab > Enable [ci-skip]. When you include [ci-skip] in your build this commit won't trigger the build in jenkins at all.

Example

build_number = increment_build_number
commit_version_bump(message:"[ci-skip] Version Bump to #{build_number}")
git_commit(path:"./CHANGELOG.md", message:"[ci-skip] Updated CHANGELOG for Build #{build_number}")
push_to_git_remote

Test Results and Screenshots

To show the deployment result right in Jenkins

  • Add post-build action
  • Publish JUnit test result report
  • Test report XMLs: fastlane/report.xml

To show the generated screenshots right in Jenkins

  • Add post-build action
  • Publish HTML reports
  • HTML directory to archive: fastlane/screenshots
  • Index page: screenshots.html

Save and run. The result should look like this:

/img/best-practices/JenkinsIntegration.png

CircleCI Integration

To run fastlane on CircleCI, first create a Gemfile in the root of your project with the following content:

# Gemfile
source "https://rubygems.org"

gem "fastlane"

and run

gem install bundler && bundle update

This will create a Gemfile.lock that defines all Ruby dependencies. Make sure to commit both files to version control.

Next, add the following to your Fastfile:

# fastlane/Fastfile

...
platform :ios do
  before_all do
    setup_circle_ci
  end
  ...
end

The setup_circle_ci fastlane action will perform the following actions:

  • Create a new temporary keychain for use with match (see the CircleCI code signing doc for more details).
  • Switch match to readonly mode to make sure CI does not create new code signing certificates or provisioning profiles.
  • Set up log and test result paths to be easily collectible.

Next, create a .circleci directory in your project and add a .circleci/config.yml with the following content:

# .circleci/config.yml

version: 2
jobs:
  build:
    macos:
      xcode: "9.0"
    working_directory: /Users/distiller/project
    environment:
      FL_OUTPUT_DIR: output
      FASTLANE_LANE: test
    shell: /bin/bash --login -o pipefail
    steps:
      - checkout
      - restore_cache:
          key: 1-gems-{{ checksum "Gemfile.lock" }}
      - run: bundle check || bundle install --path vendor/bundle
      - save_cache:
          key: 1-gems-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle
      - run:
          name: fastlane
          command: bundle exec fastlane $FASTLANE_LANE
      - store_artifacts:
          path: output
      - store_test_results:
          path: output/scan

This will do the following: Create and use a Ruby gems cache. Run the test lane on all pushes. * Collect Junit test results and store log output in the Artifacts tab.

Check out the CircleCI iOS doc for more detailed examples of using fastlane on CircleCI.

Travis Integration

Update your .travis.yml to look like this:

language: objective-c
osx_image: xcode8.3
install:
  - bundle install
script:
  - fastlane beta

The above config files assume you have a Gemfile set up, if you don't have one yet, make sure to follow our Gemfile guide and run bundle update to make sure you're using the most recent fastlane release.

Replace beta with the lane you want to run for your setup. If you want to build, sign and distribute builds from Travis, you'll need to add one more action to your Fastfile, as by default, the Travis keychain is locked.

At the top of your Fastfile, add

setup_travis

which will setup the keychain to work well with match and gym. This action will also enable the readonly mode for match, so your CI doesn't create new certificates or provisioning profiles.

Bamboo Integration

Repository setup

In bamboo under Linked Repositories (where you configure your git repo) under Advanced Settings is an option called Exclude changesets

This dialog will allow you to enter a regular expression that if a commit matches, a build will not be triggered.

For example, if your Fastfile is configured to make a commit message in the style of

Build Version bump by fastlane to Version [0.3] Build [8]

Then you could use the following regex to ignore these commits

^.*Build Version bump by fastlane.*$

Setting repository remote

By default bamboo will do an anonymous shallow clone of the repo. This will not preserve the git remote information nor the list of tags. If you are using bamboo to create commits you may want to use a code block similar to the following:

# In prep for eventually committing a version/build bump - set the git params
sh('git config user.name "<COMMITTER USERNAME>"')
sh('git config user.email <COMITTER EMAIL>')

# Bamboo does an anonymous checkout so in order to update the build versions must set the git repo URL
git_remote_cmd = 'git remote set-url origin ' + ENV['bamboo_repository_git_repositoryUrl']
sh(git_remote_cmd)

Speeding up build times with carthage

Carthage is a wonderful dependency manager but once you are start using a large number of frameworks, things can start to slow down, especially if your CI server has to run carthage EVERY time you check in a small line of code.

One way to make build times faster is to break your work up into two separate build plans (this can get even more funky if you start having multiple branches)

The general idea is to make a build plan: Project - Artifacts that builds the Carthage directory and stores it as a shared artifact. Then you create a second build plan Project - Fastlane that pulls down the Carthage directory and runs fastlane.

Artifact Plan

Use a simple setup to create this build plan. First off you want to make sure this plan is manually triggered only - because you only need to run it whenever the Cartfile changes as opposed to after ever single commit. It could also be on a nightly build perhaps if you desire.

Stages / Jobs / Tasks

This plan consists of 1 Job, 1 Stage and 2 Tasks

  • Task 1: Source Code Checkout
  • Task 2: Script (carthage update)

Artifact definitions

Create a shared artifact with the following info:

  • Name: CarthageFolder
  • Location: (leave blank)
  • Copy Pattern: Carthage/Build/**

Optional: You may want to automatically make the fastlane plan trigger whenever this plan is built

fastlane plan

When configuring fastlane to run in this setup you need to make sure that you are not calling either:

reset_git_repo(force: true)

or

ensure_git_status_clean

as these calls will either fail the build or delete the Carthage directory. Additionally you want to remove any carthage tasks from inside your Fastfile as carthage is now happening externally to the build.

Build plan setup

What this build plan does is it checks out the source code, then it downloads the entire Carthage/Build/ directory into your local project - which is exactly what would be created from carthage bootstrap and then it runs fastlane

  • Task 1: Source Code Checkout
  • Task 2: Artifact Download
  • Task 3: fastlane

GitLab CI Integration

Use GitLab Runner running on a macOS machine to build using fastlane.

Repository setup

First create a Gemfile in the root of your project with the following content:

source "https://rubygems.org"

gem "fastlane"

Add a .gitlab-ci.yml file to trigger fastlane.

stages:
  - unit_tests
  - test_flight

variables:
  LC_ALL: "en_US.UTF-8"
  LANG: "en_US.UTF-8"

before_script:
  - gem install bundler
  - bundle install

unit_tests:
  dependencies: []
  stage: unit_tests
  artifacts:
    paths:
      - fastlane/screenshots
      - fastlane/logs
  script:
    - fastlane tests
  tags:
    - ios

test_flight_build:
  dependencies: []
  stage: test_flight
  artifacts:
    paths:
      - fastlane/screenshots
      - fastlane/logs
  script:
    - fastlane beta
  tags:
    - ios
  only:
     - /^release-.*$/
     - master

See the .gitlab-ci.yml documentation for more information on how this file works.

Setting up the lanes

You should have a lane - in this example called beta - which should do the usual, match, gym, pilot, to distribute an updated Test Flight version, and one lane tests which calls scan to run UI Tests.

Auto-incremented build number.

To get an auto-incremented build number you can use something like the following lane:

lane :increment_build_number do
  increment_build_number(build_number: ENV['CI_BUILD_ID'])
end

Then the GitLab CI build ID (which iterates on each build) will be used.

Visual Studio Team Services

Microsoft Visual Studio Team Services (VSTS) and Team Foundation Server (TFS) use fastlane in their Apple App Store extension.

Getting Started

Once you have created or retrieved credentials for your App Store account, then perform the following steps to automate releasing updates from a VSTS build or release definition:

  1. Install the App Store extension from the VSTS Marketplace
  2. Go to your VSTS or TFS project, click on the Build tab, and create a new build definition (the "+" icon) that is hooked up to your project's appropriate source repo
  3. Click Add build step... and select the necessary tasks to generate your release assets (e.g. Gulp, Cordova Build)
  4. Click Add build step... and select App Store Release from the Deploy category
  5. Configure the App Store Release task with the desired authentication method, the generated IPA file path, and the desired release track.

Now when you build, your app will automatically be published to App Store Connect!

Configuring fastlane versions

The extension can be configured to install the latest version of fastlane or a specific version of fastlane:

  1. In the Build for your project, click on the Apple App Store task (supported in both Apple App Store Release and Apple App Store Promote), go to the Advanced section of the Task, click Install fastlane
  2. Optionally, select Specific Version from fastlane version, and enter a specific version of fastlane

More Information

For more documentation, see the Apple App Store in the Visual Studio Team Server marketplace.

Nevercode Integration

With Nevercode you can set up automated builds for your Android and iOS application using fastlane. You only need a Fastfile in your repository to get started.

Specify app repository

  1. Click Add a new app on Nevercode dashboard.
  2. Choose whether to add your application via supported providers using OAuth or add it manually using the other available authentication methods.

Define the lane to be built

After specifying app repository, Nevercode takes a first look at it by listing the branches in this repository. The next step for you is to select the branch you want Nevercode to scan for projects.

  1. Select a branch from the dropdown that Nevercode should scan. Note that you can change the branch later if needed.
  2. Click Scan branch. Nevercode scans the repository from the specified branch. This includes cloning the repository, looking up the available Fastfiles and listing the pre-configured lanes. All this can be monitored real-time from your browser via the live log window.
  3. Once scanning the branch has finished, choose the lane which will be executed as the main build step by Nevercode.
  4. Finalize the setup by checking the appropriate build options and click Save and start build.

External dependencies

Nevercode does not automatically install CocoaPods, Carthage or any other external dependencies for fastlane projects. Please use the fastlane's built-in actions, such as cocoapods and carthage, to gain control of that.

Code signing

To perform code signing on your iOS app, you can either follow the best practices laid out in fastlane docs, or you could also make use of Nevercode's standard code signing methods.

When invoking match from the Fastfile, keep in mind that you need to grant access to the credentials repository and expose the match passphrase during the build. Both can be securely achieved thanks to the well designed environment variable support of fastlane and Nevercode's support for several SSH keys for authentication.

In your app settings on Nevercode, navigate to the Environment tab to manage environment variables and files:

  • match passphrase can be defined as a MATCH_PASSWORD environment file — this will be automatically detected by fastlane and used to decrypt the credentials repository.
  • You can upload the SSH key for cloning the credentials repository as an environment file, i.e. MATCH_SSH_KEY. All environment files whose variable name has the suffix _SSH_KEY will be automatically added to the SSH agent and will be ready for use during the whole build process.

Run tests

iOS

Testing in Nevercode with fastlane for iOS is 100% automatic. By default, scan is used to invoke the test run, but you can easily swap it out for any other lane that you have configured for your test runs. Test results are automatically collected and you don't need to do anything to convert the results from one format to another or place them in a special location on the build machine.

Warning

In case you wish to run tests as part of the main build step, we suggest that you use Trainer to generate reliable JUnit results from the test run and put the results in a directory where we can discover them:

trainer(output_directory: ENV["NEVERCODE_XUNIT_RESULTS_DIR"])

Android

Nevercode detects your fastlane tests for Android automatically. However, tests are disabled by default and have to be enabled manually.

  1. In your app settings on Nevercode, navigate to the Test tab.
  2. Click on fastlane Gradle to expand it.
  3. Select Enabled and type the lane name for tests as specified in your Fastfile.
  4. If you would like to run the tests on Android emulator, make sure to select Require Android emulator.
  5. Click Save to finish the setup. Your fastlane tests will be enabled and run each time you build your app.

Publish your build artifacts

You can use either fastlane to take care of artifact distribution or choose from a number of Nevercode's own integrations.

Manage build versions

To make your build version management easy, Nevercode exports the NEVERCODE_BUILD_NUMBER environment variable that you can use in your build script. For instance, you could make use of it within increment_version_number action to define a new version for each build.

More Information

Check out Nevercode documentation for more.