Automated iOS Deployments with Fastlane

Typing in 17 different things to ship an app to the app store is old and busted. Hitting a button that does it all for you is the new hotness. Which do you prefer?

What is fastlane

alt

Fastlane automates the compile and deploy process for apps. It is free to use and makes the archive and submit process painless, automated and repeatable. 🎉

It was built by Felix Krause. It has been acquired by Twitter and is now part of fabric. (hat tip to Felix)

Deployment Workflow

A pretty typical workflow for us is that we ship an app to TestFlight. From there we send the app out to a set of beta testers. This lets us gather important info like:

  • User feedback: Is the app accomplishing what it is meant to? Vet new ideas -- look for ways to optimize flow in the app.
  • Bugs: Suss out any remaining niggly bugs. A beta testing group is a great way to get feedback on how the app is performing in the wild under a variety of conditions.

alt

From TestFlight we directly submit our app to the App Store for review.

When we ship to TestFlight we need to do things like:

  • Increment our build and version number for our different targets: app, notification center widgets, watch etc.
  • Commit and tag our bumped version in Git and then push our changes to our remote repository.
  • Perform our build using the appropriate scheme and provisioning profiles
  • Upload our compiled binary to TestFlight so it can be processed

Fastlane will handle all of this through an automated script. To use fastlane you simply put together a fastfile that is used to drive the deployment process. The fastfile is a recipe file that lists out each step of your process. There are some great examples inn the Fastlane GitHub repo. This fastfile gets checked-in with your code and then to deploy you simply do:

fastlane deploy

To get started using Fastlane follow the Getting Started Guide

Example fastfile

In addition these examples we wanted to share what a common recipe for us looks like and common issues we have run into.

 platform :ios do

 desc "Submit a new Beta Build to Apple TestFlight"

  lane :testflight do

  # ---------------------------
  # Make sure we don't have any unchecked in files hanging out
  # ---------------------------
  ensure_git_status_clean

  # ---------------------------
  # We better be on release branch
  # ---------------------------
  ensure_git_branch(branch: 'release')  

  # ---------------------------
  # Increment our version numbers. This needs to be done for all of our targets (app, notification center, watch etc.). Here the build and version number will match.
  # ---------------------------
  increment_version_number
  version = get_version_number()
  increment_build_number(build_number: version)

  #---------------------------
  # Commit version bump
  #---------------------------    
  commit_version_bump(message: 'Bump version', force: true)

  #---------------------------
  # Build
  #---------------------------    
  gym(clean: true, output_directory: "/tmp", scheme: "App-Release", codesigning_identity: "iPhone Distribution: Rocket Insights, Inc (N39TWRZ6R)")


  #---------------------------
  # Upload to TF
  #---------------------------    
  pilot(skip_submission: true, username: "rocketinsights@gmail.com")

  #---------------------------
  # Tag the submit
  #---------------------------    
  git_tag = "Version_" + version
add_git_tag(tag: git_tag)

  #---------------------------
  # Push to GitHub
  #---------------------------    
  push_to_git_remote(remote: 'origin', local_branch: 'release', remote_branch: 'release', force: false)

  #---------------------------
  # Clean up our files
  #---------------------------    
  clean_build_artifacts

end

Challenges

We've been using Fastlane on several different projects without any issues. It's been a fantastic addition to our toolset and one that we set-up on all of our engagements. It helps our clients stay nimble, efficient and avoid errors in the shipping process.

The set-up is pretty painless. The only road bumps that we have run into are:

  • Locked Keychain: On CI machines the keychain will typically become locked. If you receive code sign errors saying the Keychain is locked then you need to unlock it. To do that you can do the following in your CI script before kicking off fastlane.

    security unlock-keychain -p <password> /Users/<automation-user>/Library/Keychains/login.keychain
    
  • Locked Networks: Some corporate networks are locked down and don't allow certain protocols. The pilot command that uploads to iTunes uses ssh. If a network does not allow ssh you can use WebDAV instead for the upload process. To do this put the following into your shell config. (E.g., .bashrc file)

    export DELIVER_ITMSTRANSPORTER_ADDITIONAL_UPLOAD_PARAMETERS="-t DAV"
    
  • Certificate/Provisioning Profile: When you build for shipping to the app store you want to ensure that you build with the correct provisioning profile. We chose to explicitly specify the provisioning profile to use in our Build Settings. The machine you are building on must have the distribution certificate installed in its keychain. Simple and straightforward and works overtime.

Here are some links that we have found useful:

Happy Deploying!

alt

We're always looking for ways to improve our customers engineering infrastructure. Fastlane has been a huge win for deployment and is a tool we will continue to use on our engagements.