Automatic Android releases using Fastlane

Carlos M
Turo Engineering
Published in
5 min readMay 1, 2018
Photo by chuttersnap on Unsplash

Here at Turo, we have a fixed shipping schedule that consists of weekly releases. By having regular releases distributed evenly in time, all the teams are aware of the release state, making it easier to be on the same page. Similarly, our users have a sense of when to expect new features and app improvements on their devices.

The release pipeline has been performed entirely by hand for years. If you work with Android, your release pipeline probably will look similar to ours, and also will likely use the same or very alike tools. If that’s the case, you probably already know that a process can take a long time. Because of that, we decided to spend some time looking for alternatives, and we ended up opting for Fastlane.

But to better understand the necessity of automating the process, let’s take a look at our release pipeline in detail.

Release flow at Turo

The Android team at Turo uses the GitFlow branch strategy. We have a master branch, where the code in production lives, and a develop branch, where we keep code that will ship in the next release. When we have to implement a new feature or fix a bug, we branch of develop. After adding the new code, we open a pull request that after reviewed is merged back to develop.

Also, we manage our tasks using JIRA. User stories are divided into subtasks, each of them associated with a pull request. After the pull request is merged, the corresponding subtask is moved to the Done column, and tagged with the next release number.

At the beginning of the week, we start our release process with the intention of shipping the features completed during the previous week.

  • Using GitFlow, we create a release branch based off develop, that looks like this: r/{major}.{minor}.{patch}. That branch contains the code of the release candidate of the week, and allows the rest of engineers to continue merging features in develop. We will ship that features in the next release.
flow release start 2.10.0
  • Although we have a great suite of unit and integration tests, we do some manual testing of the critical flows of the release candidate to make sure we didn’t break anything. We use Beta, by Fabric, to distribute the release candidate to the Android, QA and Product teams. The engineer in charge of the release (friendly named “release master” internally) that week compiles the RC locally and uploads the APK file to Fabric.
  • After fixing any bug we find in the release branch, we bump the version in our build.gradle file and commit that to the branch. We have Gradle properties for the version numbers:
versionMajor = 2
def versionMinor = 10
def versionPatch = 0
  • Now we’re confident about the code about to be released, so we’re ready to ship. The release engineer compiles the release build type, obfuscated and signed with our release key. The resultant APK is uploaded to the Play Store, along with the deobfuscation file mapping.txt. If required, the screenshots and release notes are also updated. We usually do rollouts, increasing the adoption target and monitoring Crashlytics for bugs that we could have missed.
  • Finally, we release the shipped version in JIRA, which triggers a Release changes email to keep the rest of the teams up to date. Similarly, we publish the milestone in GitHub, and upload a copy of the debug and release APKs for future references.

As mentioned before, this is a long and slow process that blocks the release engineer most of the day. We all agreed on something: This needs to change.

What is Fastlane?

Fastlane is a helpful tool, written in Ruby, that automates tedious tasks for Android and iOS developers. It handles all tedious tasks, like generating screenshots, dealing with code signing, and releasing your application. Some of the features it offers:

  • Easily define different jobs for Play Store deployment, beta distribution or testing.
  • Can be integrated with CI frameworks.
  • Simple to extend and customize functionality and configuration.
  • All the configuration and tasks are part of your project in Git.
  • 200+ built-in integrations available (Slack, JIRA, Git, etc.).

The Fastlane related files can be found under the Fastlane folder, on the root of your project:

  • ./FastFile*: Main Fastlane file, where all the lanes (executable scripts) can be found. They can be public and executable from the command line, or private (think about them as private methods)
  • ./actions/: Folder containing all the actions, mainly Ruby services that can be created to perform all kind of tasks. Fastlane comes with a set of 100+ actions interacting with third-party services (Slack, Google Play, etc.), but for specific tasks, you can create your own.
  • ./AppFile:: Can be used to specify information that is used across Fastlane.
  • ./README.md: Auto-generated documentation updated when FastFile is modified.

Replacing manual releases with Fastlane

Step 1. Pre-release lane

This lane is the one we run when we want to start the release process. After prompting for a version number, it will create the release branch, change and commit the version number in our build.gradle file and send a beta to the Android team.

All the above will magically happen by just running the following command:

fastlane preRelease

This is the list of operation that this lane will execute automatically for you, and the tool or action used to perform it:

Operations executed by the preRelease command

Now, the team will perform a final test and notify the release master if it’s good to go.

Step 2. Complete-release lane

Once the beta sent in the previous lane is thoroughly tested, and you have the approval of the rest of the team, you’re ready to complete the release. This time Fastlane will compile the app, ship the update to the Play Store, and perform the release in JIRA and GitHub with the corresponding release notes and APK files.

This time, the command will be:

fastlane completeRelease

Below you can check the list of operation that this lane will execute automatically for you, and the tool or action used to perform it:

Operations executed by the completeRelease command

Note: When referring to private actions, we wrote our own Actions (Ruby scripts) to perform some specific actions that are not included in the built-in Fastlane integrations.

Conclusion

Fastlane allowed us to simplify a tedious release process, making it also way faster and less error-prone. Now we can dedicate the time we usually allocated for the release to build awesome features, that’s what here at Turo we love the most!

--

--