Google Play Game Build Signing
APK uploaded to Play Console, passes review — and two hours later rejection: "Your APK is not signed with the upload key." Or build accepted, but week later users report that updating Android asks to "delete old version before install" — because keystore changed between releases and Play App Signing wasn't activated in time.
Android build for Google Play less ceremonious than iOS, but key management mistakes can result in lost account or inability to update already-published app.
Keystore and Play App Signing — what's the difference
Before Play App Signing (mandatory from August 2021 for new apps) developer signed APK with their key — and user saw same key. Loss of keystore equals inability to release updates forever.
With Play App Signing scheme is two-level: upload key (in developer's hands) signs APK on Play Console upload, Google verifies it and re-signs final APK with its own app signing key before delivery to users. Loss of upload key is solvable — Google allows changing it by request. Loss of app signing key — no, but it's stored at Google.
On first publication of new app Play App Signing enables automatically. For existing apps — need explicit activation with current key upload.
Building AAB instead of APK
Since 2021 Google Play requires Android App Bundle (.aab) for new apps. Unity generates AAB via BuildOptions with BuildAppBundle = true. AAB weighs less than APK and allows Play Console to generate optimized APK for specific device (ABI split, texture compression split).
Important Unity-game nuance: using IL2CPP with AAB need to verify Split Application Binary enabled in Player Settings — otherwise AAB might exceed 150 MB upload limit. Extra assets (Addressables, StreamingAssets) should be delivered via Play Asset Delivery (PAD), not included directly in bundle.
Play Asset Delivery — mandatory topic for games with large resources. Three delivery modes: install-time (with installation, up to 1 GB), fast-follow (right after install), on-demand (by request during gameplay). Integration with Unity via Google.Play.AssetDelivery package — requires rework of asset loading system if not designed with PAD from start.
Automation via Fastlane
supply (Fastlane lane for Google Play) can upload AAB to specific track (internal, alpha, beta, production), manage rollout percentage, update store listing.
Authentication — via Service Account JSON with "Release Manager" role in Play Console. More reliable than OAuth — token doesn't expire and doesn't require interactive auth on CI.
Example of minimal Fastfile:
-
gradleaction to build AAB with needed build type - Sign via
jarsignerorzipalign+apksignerwith keystore from environment variables -
supplyto upload to internal track
Keystore stored encrypted in CI (GitHub Secrets, GitLab CI Variables, Vault). Never commit .jks or .keystore files to repo — even private.
Versioning
versionCode in Android must monotonically increase. In Unity — it's PlayerSettings.Android.bundleVersionCode. Auto-increment via script in pre-build hook or Fastlane increment_version_code. For CI builds convenient to use pipeline build number as contribution to versionCode: baseVersion * 1000 + buildNumber.
Timeline
| Task | Duration |
|---|---|
| One-time AAB build and upload to internal track | 0.5–1 day |
| Setup Play App Signing + CI keys | 1–2 days |
| Full pipeline (GameCI + Fastlane supply + tracks) | 2–5 days |
| Play Asset Delivery integration | 1–3 weeks |
Cost calculated after analysis of current project structure and signing key state.





