14.
Introduction to Fastlane
Written by Keegan Rush
Using xcodebuild and the App Store Connect API to build and manage your app can be a lot of work. Isn’t extra work what you were trying to get away from by using automation? :]
Well, you don’t necessarily need to interact with xcodebuild yourself. There’s a collection of open-source tools that interact the Xcode toolchain and the App Store Connect API, so you don’t have to.
There are some alternatives, but the most popular approach to automating iOS builds is through the use of fastlane.
At its core, fastlane is a collection of Ruby scripts that make build automation easy and accessible to iOS developers. It’s a collection of tools that wrap xcodebuild, the App Store Connect API and more:
- cert creates and maintains your signing certificates.
- sigh handles provisioning profiles.
- gym builds, signs and packages apps.
- deliver uploads apps, metadata and screenshots to App Store Connect.
- pilot uploads builds for TestFlight and handles its administration.
- scan runs your project’s automated tests.
Those are just a few of fastlane’s many actions.
Even when all you have is a superb idea for an app, fastlane can help to streamline your development process – it can even:
- Create an app record on App Store Connect.
- Manage the entire code signing process by creating provisioning profiles and signing certificates.
- Create push notification certificates.
- Take screenshots across different devices and across different languages, saving hours spent taking marketing screenshots.
If that’s not enough, fastlane also comes with a rich plugin system for you to create any action your heart desires, and share it with other users.
It’s because of all this that the iOS community has accepted fastlane as the go-to approach for build automation.
Next up, as a first step to working with fastlane, you’ll add some simple build automation for Emitron:
- Run unit tests with
scan. - If no tests fail, prepare for code signing with
certandsigh. - Build Emitron for the App Store with
gym. - Upload Emitron to TestFlight with
pilot. - Upload builds for App Store review with
deliver.
Strap yourself in; it’s time to start living life in the fastlane! :]
Getting started
In this chapter, you’ll be working with fastlane to upload builds to App Store Connect. To do so, you’ll need to make sure that the starter project’s app record, provisioning profile and signing certificate is correctly set up.
Note: To learn more about provisioning profiles, or if you need a refresher on configuring them, refer to Chapter 4, “Code Signing and Provisioning”.
To configure the starter project, refer back to the Setting up the starter project section in Chapter 13, “Build Automation”.
Note: The bundle identifier that you use for Emitron on App Store Connect should be the same as the one used throughout the book:
com.raywenderlich.emitron.pias.
Once all of that’s done, you’re ready to install fastlane.
Installing fastlane
Once you’ve finished setting up your app record, provisioning profile and signing certificate, you’ll need to get fastlane working on your computer.
There are a few ways to install fastlane. Here, you’ll use a Gemfile and bundler.
Open Terminal. Enter the following command into Terminal:
sudo gem install bundler
Bundler is a Ruby tool that manages Ruby packages, known as gems.
For Terminal to gain write permission, enter your Mac’s administrator account password when Terminal prompts for it.
In Terminal, change the directory to the starter folder’s emitron-iOS/Emitron directory. Then, enter the following command into Terminal:
touch Gemfile
You’ve created a file named Gemfile. Open Gemfile in your favorite text editor. Then, add the following content to the file:
source "https://rubygems.org"
gem "fastlane"
Bundler will use Gemfile to track your project’s gem dependencies.
Back in your terminal, run the following command:
bundle update
The update command triggers bundler to fetch any gems declared in your Gemfile.
If bundler needs sudo permissions, you’ll be prompted for your macOS account password.
Give bundler a while to fetch fastlane and its dependencies.
And that’s it! Bundler installed the latest version of fastlane. Any time you want to update to a newer version, just run bundle update fastlane.
You’ve installed fastlane, but it won’t do anything without some setup in Emitron.
Setting up fastlane
Without setting up fastlane in a specific project, it’s about as useful as an empty build script. To start using fastlane, you need to give it some information about your project.
Run this command in the terminal:
bundle exec fastlane init
Since you’re using a Gemfile, you should use bundle exec when using any of your Ruby gems. That means typing out bundle exec fastlane instead of just fastlane for each command. Using bundle exec means that you’ll get the exact version of a gem that you specified in your Gemfile, instead of a different version installed elsewhere on your computer.
Note: For any future calls to fastlane in this book, you’ll just see
fastlaneinstead of the fullbundle exec fastlane. This still works, but you’ll get a prompt to use thebundle execform instead.
fastlane init guides you through your fastlane setup. Type in 4 for manual setup. Then, press Enter to continue the setup.
Here, you get a confirmation that fastlane has generated a Fastfile and Appfile.
Fastfile is the meat of fastlane where you’ll write your actual build automation. Inside Fastfile, you’ll add your own methods called lanes, similar to methods in Swift. Each lane you create will handle a specific task, like running tests, or preparing an alpha build.
The Appfile is one of many configuration files that you can use with fastlane. By putting app-specific metadata in Appfile, Fastfile stays neat and tidy. You’ll find this pattern throughout fastlane, such as a Gymfile for use with the gym action and a Scanfile for use with scan.
fastlane will give you its own short tutorial about how it works. Read on and keep pressing Enter until fastline init finishes.
With that, you’ve fully configured fastlane and you’re ready to start using it to build and upload Emitron to TestFlight and the App Store.
Building Emitron
Before worrying about uploading Emitron to App Store Connect for TestFlight or the App Store, you’ll first automate a simple build using fastlane. You’ll gain familiarity in configuring a project for an automated build using fastlane.
In Emitron’s project folder, you’ll find a brand new fastlane subfolder. This folder contains everything to do with fastlane, including your new Fastfile and Appfile.
Open Fastfile in a text editor. Replace its contents with this:
# 1
ENV["FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT"] = "600"
# 2
default_platform(:ios)
# 3
platform :ios do
# 4
lane :build do
scan
end
end
You’ve added one lane to Fastfile named build. The purpose of this lane is to build and archive Emitron, if it passes all of the project’s unit tests.
Here’s what Fastfile does, step by step:
- As of the time of writing of this book, fastlane has a slight problem with projects using Swift Package Manager. When building your project, there’s a chance that fastlane will time out while loading Swift package dependencies. This sets the timeout to ten minutes in order to provide ample time for resolving dependencies.
- All lanes in fastlane are categorized by platform. Here, you specify that fastlane should assume that iOS is the chosen platform. With this, you don’t have to specify a platform manually when running your lane.
- Emitron is an iOS project, so you use
platform: iosfor the one and only platform section. You can think of this section as a class in Swift code. - Inside a platform, you add lanes. Here, you’re creating a lane named
build. Thebuildlane has only one action at the moment:scan.
The scan action runs your project’s test target. It’s the same as the Test action in Xcode. It’s a good first step, and you’ll build on it later.
With Fastfile in hand, you’re finally ready to take fastlane for a spin.
In the terminal, run this command:
fastlane build
Fastlane kicks off your build lane, which runs scan.
Scan doesn’t know which scheme to build for testing, so you get a prompt. Enter 3 for the Emitron scheme. Press Enter to confirm your selection.
After a couple of minutes, you’ll get a confirmation that fastlane has finished running your lane. Great work!
Wouldn’t it be great if scan didn’t have to prompt you for the scheme name? By configuring scan with all the details on how to test Emitron, it can run silently without any need for your input.
Configuring scan
In fastlane’s current state, there are no explicit directions on how scan should test Emitron.
Fastlane is built around sensible defaults, and that can get you most of the way there.
When fastlane needs more context, there are three ways to specify an action’s behavior:
- By responding to prompts when running your lane.
- By adding parameters when calling an action in Fastfile.
- Through the use of an action’s configuration file. For example, a Scanfile for the
scanaction.
If you don’t give enough instruction to scan on what it should do, you’ll get prompts to provide more info in the terminal. That’s not ideal for automation, because it opens the process up to human errors.
To avoid prompts, you can store configurations in Scanfile. This way, any calls to scan will use the values in Scanfile.
If you need to override what’s in Scanfile, you can do it by using parameters in Fastfile. The syntax is similar to a regular Swift method, for example:
scan(scheme: "Emitron", clean: true)
To get started with Scanfile, run this command in the terminal:
fastlane scan init
That creates Scanfile alongside Appfile and Fastfile.
In your text editor, open Scanfile. Replace its contents with this:
# 1
scheme("Emitron")
# 2
device("iPhone 12 Pro")
Whenever you use scan in Fastfile, it’ll use Scanfile to set its behavior. Each row in Scanfile is a parameter to scan.
Here’s what’s happening:
- Build the Emitron scheme.
- Run tests on the iPhone 12 Pro.
With that, you’re ready to run your first lane.
In the terminal, run the build once more:
fastlane build
This time, you won’t be prompted to choose a scheme.
Give it a couple of minutes, and when it’s done, you’ll get the same confirmation from before:
With your tests running smoothly, you’re ready to expand upon the build lane for further automation.
Signing and building
From code signing to app archiving, the process is infamous for causing developers headaches. You can use fastlane can automate that minus the headaches.
Starting your lane with scan is a great safety check before building Emitron for the App Store. After running tests, your build lane can compile a release build of Emitron.
Back in Fastfile, add the following to the build lane just after your call to scan:
cert
sigh
gym
See how easy it is to call fastlane actions?
The code you added doesn’t just build Emitron; it also sets up your signing certificate and provisioning profile.
Here’s what each action does, step by step:
-
cert takes care of everything to do with signing certificates. Using it here will sign your app with an existing signing certificate. If you don’t have a valid certificate on your computer,
certwill actually do the work of creating one for you! - A close companion of
cert, sigh is aptly named after the sound all iOS developers make when dealing with provisioning profiles.sighcan create new provisioning profiles or download an applicable one from the Apple Developer portal. As you have it here,sighwill download the valid provisioning profile that you’ve already set up in the Apple Developer portal. Combined withcertin your lane,sighis the last step needed to complete your code signing setup. -
gym is the workhorse that builds your app and packages it into an .ipa, ready to upload to the App Store. Instead of mucking about with xcodebuild, it’s as easy as
gym!
Note: When you use
gymto build Emitron, it’ll sign the build using the provisioning profile specified in Xcode’s Signing & Capabilities settings.It’s important that you’ve set up your project correctly, so that the profile specified in Xcode matches the valid profile in the Apple Developer portal. Take a look at Setting up the starter project in Chapter 13, “Build Automation” for more info.
Your completed build lane will run tests, prepare the appropriate certificate and provisioning profile, build Emitron, and finally package it for distribution.
Before you take the lane out for a test drive, you need to add some configuration, similar to what you did for scan.
Configuring code signing
cert and sigh both need a bit more context to function. Each of them takes their configuration from Appfile, the configuration file for project metadata.
Open Appfile in your text editor.
Replace its contents with this:
app_identifier("com.raywenderlich.emitron.pias")
apple_id("keeganrush@gmail.com")
itc_team_name("Keegan Rush")
team_id("MC7X4Q9BS6")
You need to replace the values with your own values.
Once again, each line is a parameter ready for use in your Fastfile. Here’s what each one does:
-
app_identifier is your bundle identifier, used to tell
sighwhich provisioning profile to prepare. -
apple_id is the email associated with your Apple Developer account. You’ll need to sign in when running
certandsigh. - itc_team_name is the name of your Apple Developer team, which you can find in your Apple Developer account details.
- team_id is the ID of your Apple Developer team.
For apple_id, just use the email address that you use to sign in to your Apple Developer account.
To find your team name and ID, follow these steps:
- In your web browser, navigate to developer.apple.com.
- Sign in if you haven’t already.
- Click Account in the top bar.
- Click Membership in the sidebar under Program Resources.
In Appfile, replace itc_team_name and team_id with the correct values from your membership information:
- Use your value for Team Name as the value for
itc_team_name. - Use your value for Team ID as the value for
team_id.
With those values in Appfile, both cert and sigh can run silently. You’ll still be prompted by fastlane when gym runs, however – unless you set up a Gymfile to provide configuration.
Configuring gym
To hand off the iOS apps build and package processes to fastlane, you’ll use gym. Integrating gym into your automation flow makes generating a signed ipa a breeze. gym uses the cert and sigh configurations you’ve setup earlier to sign your ipa.
In your terminal, run the following:
fastlane gym init
Similar to when you set up scan, this creates a Gymfile in the fastlane folder.
Open Gymfile in your text editor, and replace its contents with this:
# 1
scheme("Emitron")
# 2
clean(true)
# 3
output_directory("./")
# 4
export_method("app-store")
Here’s how Gymfile instructs gym to build Emitron:
- Build the Emitron scheme.
- Clean the project before building.
- Put the generated archive in the current folder, rather than in Xcode’s Derived Data folder.
- Export the archive for uploading to the App Store rather than as an ad-hoc or development build.
And that’s it! You’re ready to try out your new additions to the build lane.
Running the completed lane
With the actions you added, the build lane will now:
- Run tests.
- Prepare your code signing certificate.
- Prepare the relevant provisioning profile.
- Build, sign and package Emitron.
Before running a fastlane build, ensure you’ve selected the matching release provisioning profile and bundle identifier in the starter project as in the Appfile.
Back in the terminal, run build once more:
fastlane build
Fastlane executes each of your actions in order, starting with scan.
Once your tests have passed, fastlane moves on to cert. Here, you’ll get prompted for your password to your Apple Developer account:
There are other ways to provide the password, such as storing it as an environment variable named FASTLANE_PASSWORD. Most importantly, remember to manage your secrets well and don’t add your password to Git!
For now, enter your password in the terminal and press Enter.
Once you’re signed in, cert and sigh will carry on without a hitch.
Finally, fastlane moves on to gym. Give it a few minutes to build Emitron.
Once it’s done, you’ll get a summary of your lane and an estimation of the time you just saved by automating your workflow. With twenty-three minutes saved, that’s cause for celebration!
In the terminal, get a listing of the contents of the Emitron project folder:
ls
The output of your build lane, raywenderlich.ipa, is patiently waiting to be uploaded to App Store Connect.
Uploading to App Store Connect
When uploading to App Store Connect, you can choose to upload an app specifically for TestFlight or App Store review. To upload archived apps for their respective purposes, you’ll create two new lanes: alpha lane using Emitron’s alpha build and release lane using Emitron’s release build.
Creating the alpha lane
In Fastfile, add the following after the end of the build lane:
lane :alpha do
# 1
build
# 2
pilot
# 3
increment_build_number
end
This creates a lane to upload alpha builds to TestFlight. Here’s what’s happening, step by step:
- Run your
buildlane to build, sign and package Emitron. - Run fastlane’s
pilotaction to upload Emitron to TestFlight. - Increment the build number, rather than bumping the bundle version in Info.plist manually. This step is last on purpose. If any of the previous steps fail, the build number stays the same.
Here, you’re using the pilot action solely for uploading Emitron, but it can do much more. All of your TestFlight administration can be done using fastlane, including managing testers and distributing the builds you’re uploading.
pilot doesn’t need any further information because it gets everything it needs from Appfile. That’s the power of fastlane’s easy configuration.
If pilot successfully uploads the build, increment_build_number will then bump up Emitron’s build number to prevent errors on the next upload.
Incrementing the build number
When uploading a build to App Store Connect, one particular error plagues developers more than any other. If you happened to forget to change your app’s build version, you’ll be greeted with a familiar Redundant Binary Upload error.
Thankfully, with fastlane, your days of needing to go to Info.plist in order to bump a build version before archiving and uploading a new build are over.
Fastlane increments build numbers with the aptly named increment_build_number action. To set it up, you’ll need to make some changes to Emitron’s build settings.
Setting up increment_build_number
Fastlane can’t automatically bump your build number without changing how your project’s versioning works.
In Xcode, follow these steps to find the build settings that you need to change:
- Navigate to the project screen.
- In the left sidebar, click on the emitron target.
- Change to the Build Settings tab.
- In the search bar, search for versioning.
Here, you need to make two changes to prepare Emitron for automatic versioning.
First, set the Current Project Version to your app’s current bundle version.
You’ll find the bundle version in Info.plist:
Note: It’s important that the number you’re using for the Current Project Version and the bundle version is unique, meaning that you haven’t uploaded any builds to App Store Connect with that same version. Have a look at the Bumping the build version section in Chapter 13, “Build Automation” for more info.
If you need to set the Current Project Version and the bundle version to a unique value, do that now.
Lastly, change the Versioning System build setting to Apple Generic.
After you’re done, your versioning settings will look something like this:
From now on, your Current Project Version and bundle version will stay in sync. Every time you run the alpha or release lanes in Fastfile, both the Current Project Version and the bundle version will increase by one.
Now that you’ve set up your project versioning, that’s all the configuration you need to upload a new build to TestFlight.
Running the alpha lane
To upload a new build to TestFlight, all you need to do is to run the alpha lane.
In the terminal, run the following command:
fastlane alpha
This time, fastlane will take a little longer, because it’ll have to wait for Apple to process the build you uploaded.
Give it a moment, and you’ll get the familiar confirmation that fastlane ran your lane successfully.
Fastlane uploaded your build to App Store Connect, but the pilot action doesn’t end there. With pilot, you can also upload a changelog and all other metadata needed to submit your app for external testing.
For now, if you have any internal testers on TestFlight, the build that fastlane just uploaded will be ready and available for them to test. For the apps you share with external testers, you can even have pilot submit a beta build for review!
Note: If fastlane fails with the Redundant Binary Upload error, it means your build number still isn’t unique.
Increase the project’s Current Project Version once more and try again.
When you’re done testing the alpha build of the app, you’ll want to upload a release build.
Creating the release lane
To upload a release build of Emitron, you’ll make a new lane similar to alpha.
Back in Fastfile, add this after the end of the alpha lane:
lane :release do
# 1
build
# 2
deliver
# 3
increment_build_number
end
This new release lane is structurally similar to the alpha lane. Here’s what’s going on:
- Use the
buildlane to compile, sign and package Emitron. - Use fastlane’s
deliveraction to upload and prepare a release build. - Bump the bundle version up by one to prepare for the next build.
deliver goes far beyond uploading your build. You can use deliver to upload App Store metadata and screenshots as well, which will fill in everything you need to submit a new app for App Store review. In fact, deliver can go as far as submitting your build for review!
There’s a little bit of configuration to handle before running deliver.
Configuring deliver
In the terminal, run the following:
fastlane deliver init
Fastlane creates a Deliverfile, following the same pattern you’re used to for the other actions. Also, deliver init creates two new folders inside the fastlane folder: metadata and screenshots.
Inside metadata, you’ll find subfolders and text files corresponding to the app metadata you need to fill in before submitting your app for review.
If you’re using the snapshot action to take screenshots, or if you have your own, then the screenshots folder is where you’ll keep the screenshots that deliver should upload.
For Emitron, you won’t use deliver to upload metadata or screenshots. Because of this, you’ll have to instruct deliver to skip the upload of metadata and screenshots.
In your text editor, open the newly created Deliverfile. Replace its contents with this:
# 1
skip_metadata(true)
# 2
skip_screenshots(true)
# 3
force(true)
Here’s what’s going on, step by step:
- Tell
deliverto skip uploading metadata, essentially ignoring the contents of the metadata folder. - Similar to
skip_metadata, skip uploading screenshots in the screenshots folder. - Usually, running
deliverwill open a review page in your web browser before uploading screenshots and metadata. Settingforcetotrueskips the review page, since you’re only uploading the app. This has the added benefit of runningdeliversilently, without any user prompts.
Running the release lane
In the terminal, run your new release lane:
fastlane release
Wait for your lane to complete.
Once it’s done, you’ll see that familiar confirmation.
In App Store Connect, you’ll see your new build uploaded and ready for you to submit it for App review:
Pause for a moment; enjoy the warm, fuzzy feeling of knowing how much time you’ve just saved with automation.
You’re off to the races with fastlane!
More on fastlane
In this chapter, you’ve come a long way: from being restricted to manual builds in Xcode to an automated build pipeline with fastlane.
To do so, you only used a handful of actions:
scancertsighgympilotdeliver
However, there’s a lot more to fastlane. There are still more actions to learn about, some of which will help you to automate the perfect build pipeline for your app:
- produce creates new app records on App Store Connect.
- snapshot takes beautiful App Store screenshots for different devices and languages.
- frameit sizes screenshots and puts them in marketing frames.
- pem manages push notification profiles.
- boarding invites beta testers.
- match is an innovative new approach to code signing.
That’s a lot of functionality in one tool! In fact, fastlane isn’t only good for automating builds. In my opinion, it’s much easier to create apps, manage code signing and more with fastlane than it is via the App Store Connect site.
To learn more about these and everything else on offer, have a look at docs.fastlane.tools.
Key points
- Fastlane acts as a wrapper for
xcodebuildand the App Store Connect API. - Fastlane can be broken down into a structure of platforms, lanes and actions.
- By using the vast variety of actions, fastlane can streamline your entire build process and make other project setups much easier.
- Most fastlane actions are configurable using one of fastlane’s various configuration files.