CI/CD, Signing & Release Quiz
BUILD & TOOLING › Delivery
In Play App Signing, which key signs the APKs that users actually download from the Play Store?
- The upload key you use to send releases to Play
- The app signing key stored and used by Google
- The debug keystore key from your local Android build
- A fresh per-release key generated only for each upload
Answer: The app signing key stored and used by Google
Google strips your upload signature after verification and re-signs the delivered APKs with the app signing key it stores; the upload key only protects the path from you to Play.
A developer's upload keystore is stolen. What is the correct recovery action?
- Republish the whole app from scratch under an entirely new package name
- Nothing can be done at all; the published app is permanently lost
- Request an upload key reset in Play Console and add a new certificate
- Rotate the underlying app signing key via v3 certificate lineage
Answer: Request an upload key reset in Play Console and add a new certificate
Because the app signing key is separate and held by Google, you simply reset the upload key; existing users keep updating normally with no package change.
Why is the Android App Bundle (AAB) format required for new apps on Google Play?
- It lets Google build and sign optimized APKs for each device
- It is the only format that can be code-shrunk with R8 enabled
- APKs cannot be uploaded to the Play Console under any setting
- It removes the need to use any app signing key at release time
Answer: It lets Google build and sign optimized APKs for each device
The AAB defers final APK generation to Google, which splits and signs per density/ABI/language; this requires Google to hold the app signing key, which is why AAB plus Play App Signing is enforced.
Which Play Console track is best for a quick smoke test with a small, fixed group of internal QA users?
- Open testing
- Production with a 1% staged rollout
- Closed testing
- Internal testing
Answer: Internal testing
Internal testing supports up to 100 testers and is the fastest track to process, making it ideal for rapid internal QA before promoting to wider tracks.
What is the safest way to provide a release keystore to a GitHub Actions runner?
- Commit the .jks file and keep passwords in a checked-in gradle.properties
- Store it base64-encoded in an encrypted secret, then decode it at build time
- Hard-code the keystore passwords directly in the GitHub Actions workflow YAML
- Print the keystore in the build log so the runner can reuse it later
Answer: Store it base64-encoded in an encrypted secret, then decode it at build time
Secrets must never be committed or logged; encoding the keystore and storing it plus passwords as encrypted CI secrets, decoding only at build time, keeps them out of version control.
In Fastlane, what is a 'lane'?
- A named workflow in the Fastfile run with a single command
- A Gradle build variant generated automatically for each flavor
- A Play Console testing track used to distribute app releases
- A signature scheme version like v1, v2, or v3 for APK signing
Answer: A named workflow in the Fastfile run with a single command
Lanes are user-defined workflows in the Fastfile (e.g. lane :beta) that chain actions like gradle and supply, runnable identically on a laptop or CI server.
What credential does Fastlane's supply action need to upload a build to the Play Console?
- The app signing key exported directly from the Play Console dashboard
- The developer's personal Google account password for login
- A Google Cloud service-account JSON key with Play API access
- An OAuth token issued by the device running the app locally
Answer: A Google Cloud service-account JSON key with Play API access
supply authenticates to the Play Developer API using a service-account JSON key (json_key) that has been granted access in the Play Console; signing keys are unrelated to API auth.
During a 20% staged production rollout, your crash rate spikes. After halting the rollout, how do you get the 20% who already updated back onto a working version?
- Click 'Roll back release' in Play Console to push the previous APK to those users
- Lower the versionCode and re-upload the previous build to the same track
- You can't downgrade installed users; ship a fix with a higher versionCode
- Call the Play Developer API 'revert' endpoint to restore the prior version
Answer: You can't downgrade installed users; ship a fix with a higher versionCode
Google Play never downgrades users to a lower versionCode, and halting a rollout only stops further distribution; the only fix is a new release with an incremented versionCode.
Which APK Signature Scheme first allowed an app's signing key to be rotated using a certificate lineage?
- v1 (JAR signing)
- v2
- v3
- v4
Answer: v3
APK Signature Scheme v3 (Android 9) introduced proof-of-rotation lineage so an app can switch signing keys while staying updatable; v1/v2 have no rotation and v4 only adds incremental streaming on top of v3.
Play rejects your new AAB with an error that the version code is already used. Which rule are you violating?
- Every uploaded artifact needs a versionCode higher than any prior one
- The versionName must numerically match the versionCode on every upload
- versionCode must jump by a multiple of 100 between each released version
- Each track must have a unique applicationId suffix for its uploads
Answer: Every uploaded artifact needs a versionCode higher than any prior one
Play keys releases by an integer versionCode that must increase monotonically; reusing or lowering it is rejected regardless of the human-readable versionName.
Crash reports for your obfuscated release show meaningless class and method names in Play Console. What is missing?
- A higher logging level set in the release build for more detail
- The Play Integrity API enabled for the app’s release variant
- A separate debug build uploaded together with the release
- The matching R8/ProGuard mapping.txt file for that release
Answer: The matching R8/ProGuard mapping.txt file for that release
Play Console can only un-obfuscate stack traces when the matching R8 mapping file is present (auto-included from an AAB or uploaded manually); without it the traces stay obfuscated.
In a GitHub Actions Android pipeline, why cache the ~/.gradle/caches and wrapper directories between runs?
- It is strictly mandatory for the release signing step to even succeed
- It avoids re-downloading dependencies and reuses outputs to cut builds
- It encrypts the keystore so that it can be safely committed to git
- It is the only officially supported way to pass the AAB to the upload job
Answer: It avoids re-downloading dependencies and reuses outputs to cut builds
Dependency and build caches let later CI runs skip network downloads and reuse up-to-date task outputs, substantially shortening builds; caching has nothing to do with signing or secret handling.
You add a CI service account to the Play Console for automated uploads. Which permission setup follows least privilege?
- Make it an Admin so future tasks and uploads never get blocked
- Grant only release rights for the app and tracks it publishes to
- Share the human owner's login credentials with the automation runner
- Give it billing and user management access in case it is needed later
Answer: Grant only release rights for the app and tracks it publishes to
Least privilege means granting the service account only the release permissions for the apps and tracks it actually publishes to, limiting blast radius if the key leaks; Admin or owner credentials are over-scoped.
From a signed AAB, how do you locally produce and install the exact split APKs that Play would deliver to one connected device?
- Use bundletool to build an APK set, then install-apks to the device
- Rename the .aab file to .apk, then adb install it directly
- Run aapt2 link on the bundle, then adb push the resulting output file
- There is no local way at all; you must upload to internal testing first
Answer: Use bundletool to build an APK set, then install-apks to the device
bundletool build-apks generates a device-specific .apks set from the AAB and install-apks pushes the matching splits, reproducing Play's per-device delivery locally; an AAB cannot be installed directly.