Google Play Store CI/CD with AWS CodeBuild

Quick setup for getting play store continous delivery using AWS CodeBuild.
On this page

Google Play Store CI/CD with AWS CodeBuild

Continous delivery on Android with AWS CodeBuild

Fastlane setup

Fastlane has very good documentation on getting up and running for an Android application. For a basic app you should have lanes that at least do sanity testing and apk/bundle deployment. Lets assume we have lanes set up like:

platform :android do

  desc "Test the Android app"
  lane :test do |options|
    gradle(task: "testProdReleaseUnitTest", print_command: false)
  end

  desc "Build the Android app"
  lane :build do |options|
    gradle(task: "bundleRelease", print_command: false)
  end

  desc "Deploy the Android app"
  lane :deploy_closed_testing do |options|
    upload_to_play_store(track: "alpha", aab: "app/build/outputs/bundle/<some-flavor>/<some>.aab")
  end
end

The last task will take the specified app bundle and upload it to our closed testing (alpha) track where QA and internal testers can validate the build before sending to open beta or production.

CodeBuild setup

Log into your AWS account and create a new CodeBuild project.

Specify your source code provider.

Next choose a docker image to use for your build container. There are many good public images that are regularly maintained by the community. For this example we will use mingc/android-build-box.

It is a good idea to keep build logic tracked in VCS alongside your code. For the buildspec configuration choose Use a buildspec file.

In your Android project created a buildspec.yml file. Most tools including the Android SDK are present in the selected docker image but we choose to install bundler for fastlane usage.

 1version: 0.2
 2
 3env:
 4  variables:
 5    GRADLE_OPTS: "-Xmx4096m"
 6
 7phases:
 8  install:
 9    runtime-versions:
10      java: corretto17
11    commands:
12      - echo "Installing bundler"
13      - gem install bundler:1.17.2
14      - echo "Installing dependencies"
15      - bundle install
16  build:
17    commands:
18      - echo "Building the app"
19      - bundle exec fastlane android test
20      - bundle exec fastlane android build
21      - bundle exec fastlane android deploy_closed_testing
22
23artifacts:
24  files:
25    - app/build/*-release.aab

We elect to archive any bundles in the output matching the *-release.aab pattern. We should always store the built artifacts as a backup in parallel to the ones we upload to the Play Store. Create your build project and specify any logging settings needed.

Optional - CodeBuild build number

Something worth considering when using CodeBuild is referencing the build number in your app bundle version name or code. The build container will be populated with an environment variable called CODEBUILD_BUILD_NUMBERthat will contain the integer value of the current build. This is incrememented with each build ran and starts at 1. For example if your project uses semantic versioning you can append the build number at the end of versionName.

1// build.gradle.kts
2
3android {
4
5    defaultConfig {
6        ...
7        versionName = "1.0.0.${System.getenv("CODEBUILD_BUILD_NUMBER") ?: 9999}"
8    }
9}

Or use it as the versionCode.

1// build.gradle.kts
2
3android {
4
5    defaultConfig {
6        ...
7        versionCode = System.getenv("CODEBUILD_BUILD_NUMBER")?.toInt() ?: 9999
8    }
9}

This ensures tracability as you always know which build produced which apk (via versionName) and ensures you have an always increasing versionCode for Play Store validation.

Next steps

With this setup you should now have a CD instance that you can use to build, test, and deploy changes from your Android codebase. AWS makes it easy to incorporate this build into AWS CodePipeline if you want CD to run on new pull requests or on a schedule.