✈️ How to level up your releases with Runway — Webinar, Feb 8th at 1pm ET — Register
✈️ How to level up your releases with Runway — Webinar, Feb 8th at 1pm ET — Register

A newcomers' guide to fastlane

Mobile software development poses a number of unique challenges. The ecosystem is quite diverse: there are over six billion active smartphone devices worldwide, with a wide variety of screen sizes, processors, hardware, OS versions, languages, and features to consider. On top of that, the release process is gated and is not entirely controlled by you. You have to follow the policies and requirements set forth by Apple and Google, and these are generally getting stricter by the year.

Still, mobile development has come a long way in the past decade, and there are now a number of best practices and tools that you can lean on to make things run more smoothly. fastlane is one of those tools.

fastlane offers developers a comprehensive set of actions that help speed up and automate the mobile release process. Using fastlane, you can build and sign your binaries, run tests, deploy updates to beta users, generate marketing screenshots, submit builds to the Apple App Store and Google Play Store, and much more.

In this guide, we’ll provide an overview of how fastlane can level-up your team’s mobile release process, and we’ll compare fastlane functionality with the traditional, manual alternatives. Even if you don’t want to or aren’t able to implement your entire release pipeline in fastlane, this guide will offer some key building blocks you might want to draw from.

Don’t have a CI/CD pipeline for your mobile app yet? Struggling with a flaky one?
Try Runway Quickstart CI/CD to quickly autogenerate an end-to-end workflow for major CI/CD providers.
Try our free tool ->
Sign up for the Flight Deck — our monthly newsletter.
We'll share our perspectives on the mobile landscape, peeks into how other mobile teams and developers get things done, technical guides to optimizing your app for performance, and more. (See a recent issue here)
The App Store Connect API is very powerful, but it can quickly become a time sink.
Runway offers a lot of the functionality you might be looking for — and more — out-of-the-box and maintenance-free.
Learn more

Understanding the mobile app release process

Part of the challenge of releasing mobile apps is that there are a lot of steps involved, and many of the steps (like generating marketing screenshots and incrementing version numbers) are performed manually. This makes them error-prone and time-consuming.

Some companies attempt to address this challenge by throwing people at the problem, hiring dedicated mobile release managers or technical product managers (TPMs) to run releases. This can be expensive. Even with a great person managing your release process, as responsibility for releases moves away from the team building the product, new bottlenecks and points of failure can arise.

“Brian is the only person who knows how to do a release, and he’s on vacation, so we’ll have to wait.”

Joshua Liebowitz, Firebase Dev Summit 2017

Building a clear process, putting individuals in charge of various parts of the release, and creating robust communication channels can help safeguard against some of these stumbling blocks and improve your overall release process. This leads to specific challenges like.

By distributing the work, more people and coordination are required at each key juncture. Handoffs become critical, and any missing link in the chain causes a delay. This leads to specific challenges like the following:

  1. Build and test steps are performed on individual developers’ machines or in continuous integration (CI) environments. Differences between these environments can lead to consistency problems.
  2. Quality assurance is often performed manually by other teams or individuals and results must be communicated to engineers and stakeholders.
  3. Manual approvals are time-consuming and require teams who might be further removed from engineering to collaborate.
  4. App Store Optimization (ASO) is often done by product marketing teams who own changes to release notes, screenshots, store description, and search-driven keywords. Mistakes made during this phase can lead to app store rejection or users being unable to find your app, so it’s just as critical to your app’s success as the more technically heavy portions of the process.

This all becomes very difficult to track, and a lot of time is wasted between tasks. Automation becomes an important requirement for streamlining each of these processes, and fastlane can help with several of these steps.

What is fastlane?

fastlane is an open-source tool aimed at simplifying Android and iOS deployment by automating large portions of your mobile release workflows. It’s an extensible framework that comes with many prebuilt actions for common tasks. If you need to create your own actions, fastlane lets you do that, too.

You can use these actions collectively in lanes. For example, a complete lane for an Android app might build the application, run unit tests, take updated screenshots, generate the application bundle, and upload it to the Play Store.

In the remainder of this guide, we’ll share some specific tips for integrating fastlane actions into your existing release process, outline some key actions almost every mobile release team will want to leverage, and point you to other resources where you can learn more about fastlane along the way.

Getting started with fastlane

If you’re already using CI/CD tools to automate portions of your release, you’re in luck. fastlane has integrations with many of the major CI providers, and it’s a command-line tool that can run on any environment that runs Ruby. Once fastlane is initialized in your project, all your developers and CI environments should be able to run any of the lanes you set up.

Key elements of fastlane

Let’s look at some of the key pieces of a new fastlane project. Typically, a new fastlane project has two configuration files:

  • The <code>Appfile<code>defines configuration information that is global to your app
  • The <code>Fastfile<code> defines the lanes that drive the behavior of fastlane

The <code>Fastfile<code> is where lanes and actions are defined. By committing this file to your project’s source code, you can ensure that every developer runs the same steps when building and releasing your app.

A lane defines all the actions that should run when the lane is executed. Typically, you might have a <code>build<code> lane that builds your application’s binaries, a <code>test<code> lane that runs your tests, and a <code>deploy<code> lane that pushes updates out to the app stores.

Of course, this is just the tip of the iceberg. Your lanes can call other lanes and can handle many other tasks like taking screenshots, signing your binaries, submitting builds to TestFlight or adding builds to testing tracks in Play Console, and automatically generating changelogs. You can find lots of examples of real Fastfiles in this GitHub repository.

Installing fastlane

You can install fastlane in multiple ways, but let’s use Bundler for this tutorial.

Run `gem install bundler` to install Bundler. Create a `Gemfile` in the root directory of your project, and add the following content to your Gemfile:

ruby
source "https://rubygems.org"
gem "fastlane"

Then wrap up a few housekeeping chores for your setup:

  • Run `bundle update`.
  • Add `Gemfile` and `Gemfile.lock` into version control.
  • Use `bundle exec fastlane [lane]` to execute fastlane.
  • Add `bundle install` as the first step on your CI pipeline.
  • Update fastlane by running `bundle update fastlane`.

Homebrew (macOS)

For macOS, you can use Homebrew. macOS’s preinstalled Ruby is not recommended—it can conflict with other system tools that require a specific version of any of the dependencies.

First, install the appropriate version of Ruby for fastlane, then:

sh
brew install fastlane

Setting Up fastlane

Navigate to your project directory and run the following command:

sh
fastlane init

This initializes fastlane in your project and asks you to provide a few details:

  • The package name for your application (*eg* `com.example.yourapp`).
  • The path to your JSON secret file; simply press **Enter**.
  • Whether you plan on uploading info to Google Play via fastlane. You can set this up later; for now, answer `n`.

After the initialization process, fastlane generates a configuration for you based on the information you provided.

You should be able to see the newly created `./fastlane` directory with the files `Appfile` and `Fastfile`.

Authentication

For iOS apps, fastlane lets you authenticate with either an App Store Connect API key or via an App Store Connect user account. Note that there’s more friction and potential for flakiness with the latter, now that Apple requires two-factor authentication on all App Store Connect accounts. This is especially true when using fastlane within CI or via bots. Unfortunately, using the App Store Connect API key approach limits you to fastlane actions that call official App Store Connect API endpoints, and these represent just a subset of all the functionality fastlane offers.

For authentication on the Android side, you can use a service account and API keys generated via the Google Play Console.

Automating iOS code signing

One of the biggest challenges when automating app releases on the iOS side is code signing. fastlane offers match, an action that allows your team to share a signing identity and certificates.

By putting the certificates and profiles in a shared Git repository or S3 bucket, you can set permissions such that any approved engineer can sign builds and push updates. *match* even renews expired credentials automatically.

App updates with fastlane

With some of the basics covered, let’s look at how you can use fastlane to build, test, and submit your apps. For these examples, we’ll use an Android app that’s being pushed to the Google Play Store, but fastlane offers analogous functionality for iOS apps.

Building and testing your app

Assuming that you’re using gradle for your application’s tests, you can use the gradle action to run tests in any of your lanes:

default_platform(:android)

platform :android do
 desc "Runs all the tests"
 lane :test do
   gradle(task: "test")
 end

You can also add a lane to build a release APK for your project:

 desc "Build"
 lane :build do
   gradle(task: "clean assembleRelease")
 end

If you want to use the Android App Bundle instead of an APK, replace <code>assembleRelease<code> with <code>bundleRelease<code>. Google Play won’t accept your AAB unless it’s signed. To automatically sign the release as part of your lane, you’ll need to add your signing configuration to your app’s <code>build.gradle<code> file:

android {
 // other code
 signingConfigs {
   config {
     keyAlias = 'alias_goes_here'
     keyPassword 'key_password_goes_here'
     storePassword 'store_password_goes_here'
     storeFile file('../path/to/your/keystore.jks')
   }
 }
}

With your <code>build<code> and <code>test<code> lanes ready, you can run either lane manually by calling the following in your terminal:

fastlane <lane_name>

There is much more you can do during the build and test steps. For example, fastlane includes actions for SonarQube and OCLint static code analyzers, code coverage generation, and Swift Package Manager.

Generating assets with fastlane

Another time-consuming pre-release task involves capturing screenshots of your app and uploading them to each app store. Although many teams don’t update screenshots regularly, whenever they do it’s no easy feat to generate and upload screenshots across all the necessary screen sizes and languages they support.

Fortunately, fastlane can automatically take screenshots of your app and upload the screenshots to the Play Store or the App Store.

For Android apps, fastlane uses the screengrab action. After you install the Ruby gem and set read and write permissions, you can add a UI test that runs your app and takes screenshots of specific views you want to highlight:

@RunWith(JUnit4.class)
public class ScreenshotInstrumentedTest {
 @ClassRule
 public static final LocaleTestRule localeTestRule = new LocaleTestRule();

 @Rule
 public ActivityTestRule<MainActivity> activityRule = new ActivityTestRule<>(MainActivity.class);

 @Test
 public void testTakeScreenshot() {
   Screengrab.screenshot("before_button_click");

   // Define your behavior to run the app with Espresso
   onView(withId(R.id.fab)).perform(click());
   Screengrab.screenshot("after_button_click");
 }
}

You'll need to write some instrumented tests either in Espresso or UI Automator and call the <code>Screengrab.screenshot()<code> method where you want to take a screenshot.

After you’ve added calls to take screenshots throughout your app, you can add a new lane to your <code>Fastfile<code>:

desc "Build and test for screenshots"
lane :build_test_for_screengrab do
 gradle(
   task: 'clean'
 )
 gradle(
   task: 'assemble',
   build_type: 'Debug'
 )
 gradle(
   task: 'assemble',
   build_type: 'AndroidTest'
 )
end

When you run this lane, fastlane will run your UI tests, sending the finished screenshots to the <code>fastlane/meta<code> directory. In the next section, you’ll see how to upload these screenshots to the Play Store along with other app metadata.

Submitting your app with fastlane

Now that you’ve seen how to build your app binaries, run automated tests, and take screenshots, let’s look at how to actually submit your app to the Google Play Store. fastlane’s supply action can upload your binaries, metadata, app icon, and screenshots so that when an update is pushed, everything is automatically taken care of.

As with some of the other actions above, you just need to create a new lane or update an existing one for deploying your updates.

desc "Submit a new version to Google Play"
lane :deploy do
 test()
 build_for_screengrab()
 gradle(task: "clean bundleRelease")
 upload_to_play_store(skip_upload_apk:"true", track:"internal")
end

You can see that, as part of this <code>deploy<code> lane, we have also called the other lanes previously defined in this guide. This final lane will run the unit tests, build the APKs, take screenshots, create an OBB bundle, and upload it to your <code>internal<code> track in Google Play Console. This will allow your team to download and test the update before you commit to a <code>beta<code> or <code>production<code> release track.

Conclusion

The tools available to mobile developers to automate releases have come a long way. If you’re still struggling with manual, error-prone releases that require specific team members to be present and run operations manually, it’s time to revisit your process.

Of course, changing an existing release process is also risky. If you’re new to tools like fastlane, you may want to start by implementing just a couple of the more straightforward actions (like automated tests or screenshot generation). As you build confidence in the tool and your team embraces automation, you can move on to internal and beta releases, and work your way even closer to an entirely automated mobile release proces

App Development

Release better with Runway.

Runway integrates with all the tools you’re already using to level-up your release coordination and automation, from kickoff to release to rollout. No more cat-herding, spreadsheets, or steady drip of manual busywork.

Release better with Runway.

Runway integrates with all the tools you’re already using to level-up your release coordination and automation, from kickoff to release to rollout. No more cat-herding, spreadsheets, or steady drip of manual busywork.

Don’t have a CI/CD pipeline for your mobile app yet? Struggling with a flaky one?

Try Runway Quickstart CI/CD to quickly autogenerate an end-to-end workflow for major CI/CD providers.

Looking for a better way to distribute all your different flavors of builds, from one-offs to nightlies to RCs?

Give Build Distro a try! Sign up for Runway and see it in action for yourself.

Release better with Runway.

What if you could get the functionality you're looking for, without needing to use the ASC API at all? Runway offers you this — and more — right out-of-the-box, with no maintenance required.