Android release signing, AAB build, and prerelease version codes - #107
Merged
Conversation
Release builds sign with an upload keystore when the environment provides one; local, PR, and fork builds keep producing an unsigned APK. The versionCode gains a prerelease component so rc tags no longer collide with their final release. verify-release-apk.sh learns --signed (apksigner), a new verify-release-bundle.sh checks the AAB, and the android.yml release-build job exercises the whole signing and bundling path on main before any tag.
Scope the keystore secret to the decode step and branch later steps on the exported path, reject trailing-hyphen versions instead of silently taking the final release's code, treat a blank keystore env var as absent and fail fast when the password or alias is missing, list archive entries with unzip -Z1 so a file's on-disk path cannot satisfy a content check, and verify the AAB's jar signature on the signed path since Play rejects a bundle whose signature does not match the upload key. Comments updated to match.
The derivation is release-critical pure logic, so it moves to build-logic (VersionCode.kt) where a JUnit boundary-table test covers every rule: rc ordering, the trailing-hyphen rejection, the rc99 collision, the dev and ci floor, and the major cap under Google Play's version code ceiling. build-logic is an included build whose tests no app-side task reaches, so android.yml runs them as an explicit step.
The secrets context is not available in any if condition, step-level included, so the previous step-level secret guard failed the whole workflow file at parse time. Presence is now computed once in the job env as a boolean expression, which is permitted and yields only the string true or false, so the guards work again while the keystore material itself stays scoped to the decode step.
17 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the repository half of the signing work tracked in #106.
HAWKEYE_UPLOAD_KEYSTORE,HAWKEYE_UPLOAD_KEYSTORE_PASSWORD,HAWKEYE_UPLOAD_KEY_ALIAS). Local, PR, and fork builds have no keystore and keep producing an unsigned APK, exactly as before.major*100000000 + minor*100000 + patch*100 + rc, where a final release takes 99,rcNtakes N (1..98), anddev/cibuilds take 0.v0.4.0-rc1now yields 400001 instead of colliding withv0.4.0(400099), which unblocks rc tags and Google Play uploads. Major is capped at 20 to stay under Play's version code ceiling of 2,100,000,000.verify-release-apk.shaccepts--signed, which runsapksigner verifyfrom the newest installed build-tools.verify-release-bundle.shasserts the AAB contains both ABIs and all four asset trees.android.ymlrelease-buildjob now runsassembleRelease bundleRelease, decodes the keystore from theANDROID_UPLOAD_KEYSTORE_BASE64secret when present, and verifies both artifacts, so the entire signing and bundling path is exercised on pushes to main before any tag exists.Verified locally:
0.4.0-rc1passes the existing checks with versionCode 400001.--signedfails on an unsigned APK (DOES NOT VERIFY) and passes on a build signed with a throwaway test keystore.bundleReleaseoutput and fails when pointed at an APK.beta1,rc0,rc99, and major 21 with clear messages;rc1, finals,dev,ci, and20.999.999configure cleanly.The release.yml changes that consume this (signed asset name, Play upload) come in a follow-up so this lands independently. Part of #106.