iOS Continuous Deployment with Fastlane 🚀

Andre Silva
May 10, 2018 · 8 min read
Image for post
Image for post
Illustration by André Resendes (Significa)

If you want to add Continuous Deployment (CD) to your iOS applications and you are having a hard time doing so, you have come to the right place.

We were missing an article describing the complete process of using Fastlane to perform CD safely and with a working example using a Continuous Integration (CI) service (in this case Travis CI). With this in mind, this guide will provide you a step-by-step guide for the entire process.

We have now deployed multiple applications at our company and we found the process of manually delivering the applications to the App Store is a very repeated, frustrating and time consuming process. Using Fastlane we went from a few hours of testing and deployment to just a few minutes.

This is the second article from a two part series that includes:

  1. Automated Testing (Introduces Fastlane)
  2. Continuous Deployment to TestFlight & App Store

Notes: Sample Project 📋

The entire project is available on GitHub, for you to consult and use as you please.

Requirements 🎒

  • Add the account to the project development team in Apple Developer and iTunesConnect. This will be mandatory to automatically create the necessary certificates and provisioning profiles, and also to upload the applications to TestFlight or the App Store;
  • An empty GitHub private repository to store the encrypted certificates and provisioning profiles used in your project. Don’t use or change this repository for anything else, the script will manage the repository files on its own.

By the end of the article 🎓

  • Test your application, with a pretty printing at the end;
  • Manually deploy your application from your machine, with the build version incrementing by fetching the current version from TestFlight;
  • Automatically deploy your application from your CI service.

A. Xcode Project Setup 🛠

At the time of writing and after trying to use Xcode with the Automatically manage signing selected, we concluded the only viable way to properly implement the continuous deployment was to go with a manual certificate management.

These are the steps:

  1. Create the certificates;
  2. Configure Xcode signing to the new certificates;
  3. (Optional) Register more devices.

A.1. Certificate Management using Match (from Fastlane)

fastlane match init

By the end of the script you will have created a Matchfile inside the fastlane folder. Open it and change the app_identifier and the username to your application bundle identifier and the Apple ID of the account created, respectively.

Now we need to run the command to create the certificates to the desired profile type. Since we will want to configure the Xcode project correctly, we are creating the development and the appstore types.

Run the development script, a passphrase will be prompted to encrypt and decrypt the certificates, save it since we will later need it.

fastlane match development

Proceed with the appstore script:

fastlane match appstore

Every certificate needed will be created, remember that this will create the certificates for all the devices listed in the developer account certificate manager, if you need to add more check step 3. Register Devices ahead.

A.2. Xcode Configuration

A.2.1. Disable Automatically Manage Signing

Remember to associate a specific provisioning profile with a configuration, an example using the default Xcode configurations:

  • match Development for Debug
  • match AppStore for Release
Image for post
Image for post
Xcode (Target Signing Configuration)

As you can see, we disabled Automatically manage signing and set the match created provisioning profiles to their respective configuration.

NOTE: Leave the test targets (In the picture above: NotesTests and NotesUITests) with the Automatically manage signing setting turned ON.

A.2.2. Enable Apple Generic Versioning System

This is only if you want Fastlane to manage the versioning of the application, it needs to use the Apple Generic system in order to know how it should increment the build version automatically.

To do this you can either configure the project (like the example below) or the target depending on what suits you best:

Image for post
Image for post
Xcode (Project Versioning Configuration)

A.3. Register Devices 📱

In order to register devices you will need a name and a UUID. If a device is connected to your computer, you can use Instruments to list all the connected devices and find these two parameters using the command:

instruments -s devices

After retrieving the name and UUID of the devices you can do two things:

  1. Register a single device via command line using the tool register_device:
fastlane run register_device name:"iPhone 8" udid:"d629fef002af1..."

2. Register multiple devices by using the Fastlane tool register_devices. Unfortunately there is no command line support at the time of writing and I can’t provide an example, if this changes please let me know.

NOTE: You will need to repeat the step 1. Certificate Management using Match with Forcing to update the Development provisioning profiles with the new devices.

fastlane match development --force 

The AppStore provisioning profiles are not specific to the list of devices you have registered therefore they don’t need to be updated.


B. Fastlane Setup 🚀

NOTE: If you don’t have any builds uploaded to Testflight or the App Store, you need to perform a manual deployment before you can automate the process.

We need to update the Appfile, located inside the fastlane folder, to contain the app_identifier and the apple_id these two are mandatory.

The itc_team_id and the team_id are only needed if your Apple ID is integrated into more than one team on the Apple Developers Portal and iTunesConnect.

NOTE: If your Apple ID is in multiple teams, remove the settings and run the B.1. Manual Deployment script, extract the iTunesConnect ID and the Team ID from the script log (you will be prompted to select a team) and set them in the Appfile.

Appfile (GitHub)

B.1. Manual Deployment

Fastfile — manual_testflight (GitHub)

The script will fetch all the necessary certificates, increment the build number by checking the latest build uploaded to iTunesConnect, create an .ipa file and upload it to TestFlight.

Before running the script we will need to set some environmental variables: the Apple ID password and the passphrase I said you would need later during step A.1. Certificate Management using Match.

export FASTLANE_PASSWORD=”YOUR_APPLE_ID_PASSWORD”
export MATCH_PASSWORD=”YOUR_CERTIFICATES_PASSPHRASE”

If this is the first build you are uploading, you might get a version prompted, just press Enter and it will properly get the initial version (1.0).

NOTE: If you didn’t follow step A.1. Certificates Management using Match, you will not have the necessary certificates on your computer to perform the manual deployment.

Now we only need to run the manual_testflight lane:

fastlane manual_testflight

B.2. Automatic Deployment

Fastfile — travis_testflight (GitHub)

This script will do the same thing the manual does, but will take into account an extra measure of security. It will create a locked keychain and save the certificates there and, by the end of the script, it will delete the keychain along with all the downloaded certificates.

NOTE: Do not run this lane on your personal computer, it will mess with your keychain and you might end up losing your keychain data. Use it only on the CI machines.


C. Travis CI Setup

For this step you will need five environmental variables, some are the same as before:

  • MATCH_PASSWORD = The certificates passphrase;
  • MATCH_KEYCHAIN_NAME = A keychain name (choose);
  • MATCH_KEYCHAIN_PASSWORD = A keychain password (choose);
  • FASTLANE_PASSWORD = Apple account password;
  • CI_USER_TOKEN = GitHub Personal Access Token with repo permissions, you can get it here (it will be necessary to access the private repository with the certificates).

After you get all those, you need to encrypt them onto your .travis.yml file, to do so just insert the following five commands, one by one:

travis encrypt 'MATCH_PASSWORD=YOUR_CERTIFICATES_PASSPHRASE' --add env.globaltravis encrypt 'MATCH_KEYCHAIN_NAME=KEYCHAIN_NAME' --add env.globaltravis encrypt 'MATCH_KEYCHAIN_PASSWORD=KEYCHAIN_PASSWORD' --add env.globaltravis encrypt 'FASTLANE_PASSWORD=YOUR_APPLE_ID_PASSWORD' --add env.globaltravis encrypt 'CI_USER_TOKEN=YOUR_PERSONAL_ACCESS_TOKEN' --add env.global

This will add the environmental variables directly to your travis script. Now we just need to add a command to provide GitHub access to the Travis machine duringbefore_install and execute the Fastlane lanes during scriptphase, you can check the final script below:

.travis.yml (GitHub)

Time Saving Tip 🕐

Set the key ITSAppUsesNonExemptEncryption boolean to NO, remember you should only use this if it applies to your project (more info here).


Thank you for reading! 😊

Thank you so much for reading and if you enjoyed this article make sure to hit that 👏👏 button. It means a lot to us! Also don’t forget to follow Coletiv on Medium, Twitter, and LinkedIn as we keep posting more and more interesting articles on multiple technologies.

In case you don’t know, Coletiv is a software development studio from Porto specialised in Elixir, iOS, and Android app development. But we do all kinds of stuff. We take care of UX/UI design, web development, and even security for you.

So, let’s craft something together?

Coletiv

Thoughts, dreams and rants about technology and work life…

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store