bundletool build-apks: From AAB to Installable APKs in CI
bundletool build-apks converts an Android App Bundle (.aab) into an .apks archive of device-specific splits, or a single universal APK with --mode universal.
Google Play consumes .aab files, but to install one on an emulator in CI you need bundletool to expand it into APKs. The universal mode gives a single installable APK for smoke tests.
What it does
bundletool build-apks reads an .aab and generates an .apks container of the APK splits Play would serve. --mode universal instead produces one fat APK that runs on any device. bundletool install-apks pushes the right splits to a connected device; extract-apks pulls them for a specific device spec.
Common usage
java -jar bundletool.jar build-apks \
--bundle=app-release.aab --output=app.apks \
--ks=release.keystore --ks-key-alias=upload \
--ks-pass=env:KS_PASS --key-pass=env:KEY_PASS
# single installable APK for a smoke test
java -jar bundletool.jar build-apks \
--bundle=app-release.aab --output=universal.apks --mode=universal
java -jar bundletool.jar install-apks --apks=app.apksOptions
| Flag | What it does |
|---|---|
| --bundle=<aab> | Input Android App Bundle |
| --output=<apks> | Output .apks archive |
| --mode=universal | Produce one APK that installs on any device |
| --ks / --ks-key-alias | Keystore and alias to sign the generated APKs |
| --ks-pass / --key-pass env:VAR | Passwords from the environment |
| install-apks --apks=<file> | Install the matching splits to a device |
In CI
Use --mode=universal to get a single APK you can adb install onto the emulator for smoke tests. Sign the generated APKs with the same keystore your release uses (from a secret) so they install and match. bundletool is a JAR, so a JDK must be on the runner.
Common errors in CI
"The APKs are unsigned" (later, at install) means you omitted the --ks flags. "Unable to load keystore" means a wrong --ks path or password. "INSTALL_FAILED_NO_MATCHING_ABIS" installing a split set means the device ABI is not covered; use --mode=universal for the emulator. "Bundle targets ... but the connected device ..." means install-apks could not match a split to the device.