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_NUMBER
that 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.