Tag what a release uploaded instead of what it was meant to upload - #568
Open
andiwand wants to merge 1 commit into
Open
Tag what a release uploaded instead of what it was meant to upload#568andiwand wants to merge 1 commit into
andiwand wants to merge 1 commit into
Conversation
A tag had to be pushed before the run it named, which is a promise the run can fail to keep. v4.9.0 is the case in point: its tag push run failed and the upload came from a dispatched run instead. The same commit that time, but nothing made it so - a dispatch off main builds whatever main is at, and a release uploaded from the fix-play-store-upload branch has no tag naming it anywhere. So the tag stops being the trigger and becomes the record. release.yml is dispatch-only, and writes build/<flavor>/<version> at the commit it uploaded, as each lane lands rather than once at the end: the half uploaded release is the case the record exists for, and a lite failure must not take pro's tag down with it. Per flavor for the same reason - the two halves get finished from different commits. The plain v* tag stays a human decision, taken once the release is actually live, and no longer builds anything. What it does run is attach-apk.yml, which is the old attach job moved out: it fetches the pro apk from the run that uploaded it and puts it on the github release. Attaching had to move anyway, since it keyed off a trigger tag that no longer exists, and it is better placed here - it now attaches the apk that went to play rather than one built alongside it, and it refuses a version tag that does not sit on the commit build/pro/<version> names. resolve-version.py loses its tag arm; the input is the only source. CHANGELOG.md gets the matching rule: the heading is cut when the version is dispatched, not when it is tagged, because a version code can only be uploaded once and no later commit can ever ship under it. Untested end to end, since a real run uploads to the play store. Both workflows parse, the run blocks are shellcheck clean, the tag round trip and the flavor loop were exercised in a scratch repo, and resolve-version.py was run across all its cases. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RsdTta67FZ4KeNfPPw5BVL
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.
Follows #567.
A version tag had to be pushed before the run it named, which is a promise the run can fail to keep.
v4.9.0is the case in point: its tag push run failed, and the upload that shipped came from a dispatched run instead. Same commit that time, but nothing made it so — a dispatch offmainbuilds whatevermainis at, and there is a successful release run on thefix-play-store-uploadbranch with no tag naming it anywhere.So the tag stops being the trigger and becomes the record.
What changes
release.ymlis dispatch-only. Thepush: tags:trigger is gone;versionis the only source.It tags what it uploaded, as
build/<flavor>/<version>, at the commit it built. Written as each lane lands rather than once at the end — the half uploaded release is the case the record exists for, and a lite failure must not take pro's tag down with it. Per flavor for the same reason: the two halves get finished from different commits. Needscontents: write.The Android version code is derived (
v4.14.0→40800), not counted from the store, so unlike the iOS version of this there is no build number to carry and no second build of a version to disambiguate — Play refuses a version code it has already accepted. That also gives a free fast-fail: a version already tagged as uploaded is now caught in seconds instead of six minutes in.The plain
v*tag stays manual, pushed once the release is actually live, and no longer builds anything:git tag v4.14.0 build/pro/v4.14.0^{} && git push origin v4.14.0attach-apk.ymlis the oldattachjob moved into a workflow of its own, triggered by that tag. It had to move — it keyed off a trigger tag that no longer exists — but it is better off here:build/pro/<version>names, which is the one thing that catches the two drifting apart, and errors if lite never went out at all;Run artifacts are kept 90 days, so a version tag written much later has no APK left to attach; that is checked with a message rather than left to
download-artifact.resolve-version.pyloses its--tagarm and the tag/input agreement check. The "only a dry run may go without a version" guard is untouched.CHANGELOG.mdgets anUnreleasedheading and the matching rule: the heading is cut when the version is dispatched, not when it is tagged, because a version code can only be uploaded once and no later commit can ever ship under that version. It also now says it is not the store copy —skip_upload_changelogs: true, so what Play shows is written in the Console.Notes
The
v4.7tag that reached origin on the 3rd and started a full release run of a week-old commit cannot happen after this: av*tag now runsattach-apk, which fails in seconds on a missing build tag instead of building and signing anything.A lane run from a laptop still leaves no tag, so an upload made by hand is not recorded. That is the same as before, and seemed worse to paper over than to state in the README.
Untested end to end, since a real run uploads to the Play Store. Both workflows parse, the
run:blocks are shellcheck clean apart fromenv:-supplied variables it cannot see, the tag round trip and the flavor loop were exercised in a scratch repo, andresolve-version.pywas run across all its cases.🤖 Generated with Claude Code