Skip to main content

Set up the module

Any module that applies the Android application plugin is picked up, in a Kotlin Multiplatform project or on its own:

Release or debug

What the platform builds depends on the keystore secrets: The file names are the ones Gradle gives them: the module name, then the variant. With product flavors you get one file per flavor. A debug build carries a note that says how to get a signed one. A debug APK installs on test devices but cannot go to a store.

Signing

Store the keystore and its passwords as secret env vars for builds. Secret values are stored encrypted, are never shown again, and are masked in build logs. To keep the passwords out of your shell history, write them to a .env file, import it as secrets, and delete the file:
On macOS, use base64 -i upload.jks instead of base64 -w0 upload.jks. You can also paste the values in the project’s Env tab. The platform checks the secrets before it builds. If the base64 is broken, the keystore does not open with the password, the alias is not in it, or the key password is wrong, the Android target fails with that reason. You do not need a signing config in your Gradle build: the platform sets one on the release build type for you, and the keystore never has to be in your repository. The secrets are read from the environment being built, so previews can use another key, or none to get debug builds. See Environment variables.

Getting the files

The APK and the App Bundle are artifacts of the deployment. You find them:
  • in the panel, on the deployment;
  • at the end of atoll deploy, under the Android target:
The platform keeps the files of the last 10 finished deployments per project and environment. Download builds you want to keep longer.

Google Play

The platform can upload the signed App Bundle of every release build to the internal testing track of Google Play:
  1. Create the app in the Play Console. The platform uploads to an existing app; it does not create one.
  2. Create a Google Cloud service account, give it access to the app in the Play Console, and download its JSON key.
  3. Store the key as a secret build env var named PLAY_SERVICE_ACCOUNT_JSON:
After each release build, the Android target gets a note with the result, e.g. “Uploaded version 42 to the Google Play internal track.” For an app that is still a draft in the Play Console, the release is uploaded as a draft; roll it out there. Raise versionCode for every build you want uploaded. A failed upload does not fail the target: the files are built and attached either way, and the note says what went wrong. With several release variants, Google Play gets the one of the default flavors, else the first. Debug builds are never uploaded.

When the Android build fails

The Android target fails on its own. Targets that did build still go live, and the deployment ends as PARTIAL. See Deployments. A self-hosted server that builds on its own host (not on Kubernetes) and has no Android SDK skips Android targets instead. They show as SKIPPED with “No Android SDK on this build host”, and do not count as failures. The Kubernetes builder image includes the SDK.