Repository navigation
Publish the release when a re-pushed tag leaves it as a draft - #42
Merged
Merged
Conversation
Deleting a tag reverts its GitHub release to a draft -- it keeps its body and assets and stops being visible -- and `gh release edit` leaves that flag exactly as it finds it. So an edit after a tag is deleted and re-pushed goes green having republished nothing: correct tag, invisible release. This repository shows the residue of that mechanism already. The v1.0.0 and v1.0.1 releases have been drafts since those tags were withdrawn, and they outlived the tags themselves. It was found as a live failure in laranail/validation-js, whose release had to be published by hand. Both editing paths now pass --draft=false: release.yml when it updates an existing release, and release-benchmark.yml when it injects the table, which runs by workflow_dispatch too and so can reach a draft. Nothing else reports that state. The tag resolves, composer installs and the tag-currency check passes, because none of them reads the release -- so the guard reads every workflow file rather than these two call sites, counts the files, and requires at least two commands so a call site that disappears fails too. The first comment in release.yml said v0.1.0 is force-pushed on every change. v0.1.1 was cut on 2026-11-02, so that premise no longer holds; the idempotence it argued for still does, for a re-pushed tag.
Benchmark results
|
This was referenced Nov 8, 2026
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.
Summary
Deleting a tag reverts its GitHub release to a draft — it keeps its body and assets and stops being visible — and
gh release editleaves that flag exactly as it finds it. So an edit after a tag is deleted and re-pushed goes green having republished nothing: correct tag, invisible release.This repository already shows the residue.
gh release listreturnsv1.0.0andv1.0.1as drafts, from 2026-08-24, left behind when those tags were withdrawn in the floor-to-v0.1.0reset. The drafts outlived the tags: neither tag exists on the remote any more.It was found as a live failure in
laranail/validation-json 2026-11-08, whose release had to be published by hand (validation-js#35). Herev0.1.1, the current release, is published — so nothing is hidden today.Nothing else reports that state. The tag resolves,
composerinstalls, andcomposer tag-currencypasses, because none of them reads the release — so a failed run is not the only way to end up with a correct tag and no release. A successful one will do it too.What changed
Two call sites, because both edit a release:
release.ymlon its update path.release-benchmark.ymlwhen it injects the benchmark table. This one also runs byworkflow_dispatch, which can reach a release that is a draft — on therelease: releasedpath it cannot, since that event only fires for a published release.Plus:
tests/ReleaseWorkflowTest.php(new) asserts the flag across every workflow file rather than these two call sites, so a workflow added later inherits the rule. It counts the files it read (floor 13), fails when nogh release editmatches at all, and requires at least two commands, so a call site that disappears fails too.docs/release.mdgains "A deleted tag leaves its release behind as a draft", naming the two orphans; the CHANGELOG records it under[Unreleased].release.yml's first comment claimedv0.1.0"is force-pushed on every change".v0.1.1was cut on 2026-11-02, so that premise no longer holds — the idempotence it argued for still does, for a re-pushed tag, so only the premise changed.Proof the guard can fail
Each defect injected separately, restored byte-exact, green again after each:
release.ymlloses the flagrelease-benchmark.ymlloses itGates
laranail-pint --testpassed ·phpstan analyse(level max) 0 errors ·rector process --dry-runclean, with this file's two rewrites applied rather than left for thechore: rectorjob.composer test: 6155 passed of 6280, 123 skipped, 2 failed —StringRuleTest::it validates string with activeUrlandFluentRuleTest::it validates activeUrl shortcut. Both need DNS, and this sandbox has none:php -r 'var_dump(checkdnsrr("google.com", "A"));'printsbool(false), soactive_urlcannot pass locally regardless of the change. They are unrelated to this diff, which touches two workflows, two docs and one new test file.The local vendor directory also held
laranail/package-tools v0.1.2against a declared^0.1.10, so the suite could not boot untilcomposer updatewas run. A stale local install, not a repository change.