Skip to content
Latchkey

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

Terminal
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.apks

Options

FlagWhat it does
--bundle=<aab>Input Android App Bundle
--output=<apks>Output .apks archive
--mode=universalProduce one APK that installs on any device
--ks / --ks-key-aliasKeystore and alias to sign the generated APKs
--ks-pass / --key-pass env:VARPasswords 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.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →