ci: fail closed if a pre-release tag would publish to Play production - #245
ci: fail closed if a pre-release tag would publish to Play production#245TimeToBuildBob wants to merge 2 commits into
Conversation
The tag→track mapping already sends X.Y.Z to production and everything else to internal (ActivityWatch#182). This makes that contract executable: resolve via scripts/assert-play-track.sh, write the track into the job summary, and refuse to run supply when a pre-release tag would hit production. Also drop the leftover test-job `SUPPLY_TRACK: production` env (it never reached fastlane) so it cannot be copied onto the publish job. Git-Session-Id: 5802
Greptile SummaryThis PR adds a tested Play-track resolver and assertions intended to prevent pre-release tags from reaching production. It also removes the unused test-job track variable, records the selected track in the job summary, and rechecks it before Fastlane runs, but the selected value is not forwarded to the upload command. Confidence Score: 4/5The PR should not merge until the asserted Play track is explicitly passed to Fastlane, because a pre-release upload can still use the production default. The resolver correctly derives and validates an internal track for pre-releases, but the actual supply invocation omits that value, leaving the publication behavior disconnected from the new guard. Files Needing Attention: .github/workflows/build.yml Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart LR
Tag[Release tag] --> Resolve[Resolve SUPPLY_TRACK]
Resolve --> Assert[Assert tag and track agree]
Assert --> Supply[Fastlane supply]
Supply --> Default[Fastlane track selection]
Resolve -. SUPPLY_TRACK not forwarded .-> Supply
Default --> Play[Google Play]
Reviews (1): Last reviewed commit: "ci: fail closed if a pre-release tag wou..." | Re-trigger Greptile |
| # This is idempotent (exits 0 if already present). | ||
| gem sources --add https://rubygems.org | ||
| # Re-check at the publish boundary: the env that actually reaches supply. | ||
| bash scripts/assert-play-track.sh assert "${{ github.ref_name }}" "${SUPPLY_TRACK}" |
There was a problem hiding this comment.
Asserted track never reaches Fastlane
When a pre-release tag reaches this job, the resolver and assertions accept SUPPLY_TRACK=internal, but fastlane supply run is invoked without that track, causing Fastlane to use its production default and publish the pre-release AAB to production.
Knowledge Base Used:
There was a problem hiding this comment.
Fixed in 5e935bf: fastlane supply run now takes --track "$SUPPLY_TRACK" so the asserted value is on the argv that uploads.
Historical path was SUPPLY_TRACK via GITHUB_ENV (fastlane maps that onto supply's track; default is production). Env still gets set; --track is the fail-closed copy so a missing env cannot silently fall back to production.
supply defaults to production. The historical path was SUPPLY_TRACK via GITHUB_ENV; pass --track explicitly so the asserted value is the one that actually uploads. Git-Session-Id: 5802
Why
#243 reported a GitHub pre-release (
v0.14.0b2) reaching production Play devices. Erik confirmed that was an intentional Play Console promotion from the internal track, not a CI mapping bug (comment).The CI mapping itself is already correct after #182:
X.Y.Z→production, anything else →internal. What was missing is a fail-closed assert at publish time, so a later regression (or copying the leftover test-jobSUPPLY_TRACK: productionenv onto the publish job) cannot silently ship a pre-release tag to production.This does not close #243. Play Console can still promote a track by hand; that is how b2 reached production. The remaining user-facing work on that issue is the bucket-migration path (
aw-android-test-bucket-migration-merge/ #244), not CI.What changed
scripts/assert-play-track.sh— resolve + assert +--self-test(stablev0.14.0→ production;v0.14.0b2/dev/rc→ internal;production+ pre-release tag → hard fail).release-fastlaneuses the script to setSUPPLY_TRACK, writes tag+track to the job summary, asserts after resolve, and asserts again immediately beforefastlane supply run.--self-teston every PR and drops the unused job-levelSUPPLY_TRACK: production(it never reached fastlane).Overlap
#212 also edits
build.yml(signing hardening). Different hunks; rebase this if #212 lands first.Test plan
bash scripts/assert-play-track.sh --self-testresolve v0.14.0b2→internalassert v0.14.0b2 production→ exit 1Assert Play-track resolvergreen on this PR