Mathew Brown

Fastlane for a Small Android App

Table of Contents

C2K ships through F-Droid and Google Play, with store listings in six languages. Releasing it means building the right artifact, updating release notes, updating or creating screenshots, updating store descriptions, signing the build, creating a tag, calculating a checksum, and sending everything to the right place.

I don't want to remember every command each time.

That is what Fastlane does for me.

What Fastlane is

Fastlane is an open-source automation toolkit for Android and Apple platforms. It handles common mobile-development jobs through named workflows called lanes in a Ruby file named Fastfile. A lane can call Fastlane actions, shell commands, Gradle, or other tools used by the project.

I started using Fastlane because of F-Droid. F-Droid looks for descriptions, screenshots, and changelogs under fastlane/metadata/android/. It only requires the directory format. I could have managed those files by hand, but Fastlane could also automate the release work around them.

Fastlane doesn't replace Gradle, Docker, or GitHub Actions; it coordinates them.

What it does for me

I don't release C2K every day. Enough time passes between releases for details to become fuzzy. Which Gradle task builds the foss variant? Which artifact gets signed? Did I update every language? Which command uploads store copy without touching the app bundle?

The Fastfile answers those questions. It records the commands, their order, and their defaults. It also lives in the repository, where I can review changes to the release process with changes to the app.

I use Fastlane when it makes a multi-step workflow easier to understand. I don't wrap every build command in a lane.

How C2K uses Fastlane today

C2K has four lanes: screenshots, playstore, metadata, and release.

Localized screenshots

The screenshots lane builds the foss debug APK and its test APK, then runs Screengrab:

lane :screenshots do
  gradle(task: "assembleFossDebug assembleFossDebugAndroidTest")
  capture_android_screenshots
end

Compose UI tests navigate through C2K and capture seven store-listing screens with predictable data. Screengrab runs the tests for every configured language and saves the images with the store metadata. The Screengrab documentation notes a useful side effect: localized screenshots expose clipped translations and layout problems.

Google Play and metadata

The playstore lane builds the release Android App Bundle and sends it to Google Play with the checked-in descriptions, changelogs, and other store metadata.

It defaults to Google Play's private internal testing track and validation mode. Running the lane checks the bundle and metadata without publishing. A production release must be explicit:

bundle exec fastlane playstore track:production validate_only:false

The lane skips images and screenshots unless I ask for them. Those files rarely change, and uploading the same set for six languages adds time and unnecessary network calls.

The separate metadata lane checks titles and descriptions without uploading an app bundle, images, screenshots, or changelogs. It also defaults to validation mode. Adding validate_only:false publishes the copy without creating a new app release. The Google Play action documentation covers the other upload and release-track options.

F-Droid and GitHub releases

F-Droid builds C2K from source after it discovers a new version tag. The release lane prepares that tag and a separate GitHub release.

It performs the following steps:

  1. Require a clean Git worktree.
  2. Read the version name and code from the Gradle configuration.
  3. Create the version tag locally.
  4. Run the reproducible build inside Docker.
  5. Sign a copy of the APK for the GitHub release.
  6. Calculate and display its SHA-256 checksum.
  7. Pause for confirmation before anything becomes public.
  8. Push the tag and create the GitHub release with its changelog and checksum.

The signed APK belongs to the GitHub release. F-Droid uses the tag to build from source and applies its own signature.

The lane builds and signs the GitHub APK before asking me to publish. I see the artifact and its hash while the tag remains local.

What comes next

The next addition will probably be a preflight lane. It could confirm the version bump, check that each language has a changelog, run tests, verify the worktree, and build the expected artifacts. One command would tell me whether the release is ready without publishing anything.

Later, GitHub Actions could send tagged builds to Google's internal testing track, and the screenshot lane could cover tablets and foldables.

That is the payoff for me.

The next time I release C2K, I won't have to remember how I did it last time. The answer lives in the repository.