feat(release): remind on milestone instead of automating the release - #648
Merged
Merged
Conversation
Removes the machinery that tried to drive a release, and replaces it with a reminder early enough to act on. Why the automation could not be made safe. GitHub fires no workflow for the created, edited or deleted activity types on DRAFT releases, so nothing can prepare anything while a release is still a draft, and the tag exists the instant Publish is clicked. A stale version stamp at that moment could only be repaired by moving the tag -- and a published tag must never move, because every one is recorded in sum.golang.org, where a moved tag gives existing consumers a checksum mismatch that reads as a supply-chain compromise. Any workflow doing that is racing the module proxy. So the stamps have to be right BEFORE the tag exists, and the reliable way to get there is a reminder, not machinery. Release Checklist opens an issue when a version milestone is created, listing every version and where it lives: the four celeris stamps that CheckRelease enforces, and the work in loadgen, probatorium and docs that nothing enforces at all. The body is generated from the same list CheckRelease uses, so it cannot drift from what is actually checked. The stamp facts and the renderer move to internal/release, because the mage files are package main behind a build tag and nothing in them is reachable by go test ./... . A checklist that drifts would send someone to edit a file that no longer carries a version. release.yml keeps only what cannot get the version wrong, because it reads it off the tag: verify the stamps, tag the sub-modules, warn the proxy. The dispatch path and the job that created the tag are gone. Nothing downstream runs if the gate fails, and that condition is now an explicit success check rather than a skipped-counts-as-fine one. CheckRelease and PrepRelease are untouched. Neither is release automation: one reports drift on every pull request, the other is a single command the checklist tells you to run. Controls: hardcoding the stamp list instead of iterating it, dropping probatorium from the unenforced list, hardcoding the version, and loosening the version pattern so a non-release milestone would get a reminder -- each fails its test, naming what it broke.
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.
Removes the machinery that tried to drive a release, and replaces it with a reminder early enough to act on.
Why the automation could not be made safe
GitHub fires no workflow for the
created,editedordeletedactivity types on draft releases. So nothing can prepare anything while a release is still a draft, and the tag exists the instant Publish is clicked.A stale version stamp at that moment could only be repaired by moving the tag. A published tag must never move: every one is recorded in
sum.golang.org, where a moved tag hands existing consumers a checksum mismatch that reads as a supply-chain compromise. Any workflow attempting that repair is racing the module proxy.The stamps therefore have to be right before the tag exists, and the reliable way to get there is a reminder, not machinery.
What you get instead
When a version milestone is created, an issue opens titled
Release checklist: vX.Y.Z, assigned to that milestone, listing every version and where it lives. Milestones for the non-release tracks are ignored.This is what it renders for
v1.7.0:Opened automatically because the v1.7.0 milestone was created. Close it when every stamp below reads
1.7.0.Only the celeris stamps are enforced:
mage CheckReleaseruns in Lint on every pull request and fails while any of them disagrees. Everything under the second heading is enforced by nothing, which is why it is written down here.celeris — enforced by
mage CheckReleaseOne command does all of these:
Or by hand:
server.go→const Version = "1.7.0"README.md→## What's new in v1.7.0middleware/compress/go.mod→github.com/goceleris/celeris v1.7.0middleware/metrics/go.mod→github.com/goceleris/celeris v1.7.0middleware/otel/go.mod→github.com/goceleris/celeris v1.7.0middleware/protobuf/go.mod→github.com/goceleris/celeris v1.7.0README.md— replace the placeholder under that heading with the real release prose.CheckReleasefails while the placeholder remains, so this one cannot be forgotten silently.The other three repositories — enforced by nothing
version.go,const fallbackVersion— only if loadgen is being released too; it versions independently of celeris.internal/integrationtest/testserver/go.mod— the celeris pin.After you publish the release
These run on their own from
.github/workflows/release.yml. They are listed so a failure is recognisable rather than invisible:middleware/compress/v1.7.0is taggedmiddleware/metrics/v1.7.0is taggedmiddleware/otel/v1.7.0is taggedmiddleware/protobuf/v1.7.0is taggedNeither runs if the stamps disagree. A sub-module tag pinning the wrong celeris version cannot be corrected afterwards: every published tag is recorded in
sum.golang.org, and moving one gives existing consumers a checksum mismatch that reads as a supply-chain compromise. The remedy for a bad published version is always a new version.Why it cannot go stale
The body is generated from the same list
mage CheckReleaseenforces, so adding a stamp adds a line. Those facts move tointernal/releasefor one reason: the mage files arepackage mainbehind a build tag, so nothing in them is reachable bygo test ./...and none of it was covered. A checklist that drifts is worse than none, because it sends someone to edit a file that no longer carries a version.What is left of release.yml
Only what cannot get the version wrong, because it reads it off the tag you created: verify the stamps, tag the four sub-modules, warm the Go proxy. The
workflow_dispatchpath and the job that created the tag are gone.Nothing downstream runs if the gate fails, and that is now an explicit success check rather than treating a skipped upstream job as permission to continue. An earlier version of that condition did exactly that and burned a version on the proxy after the gate had declined it.
CheckReleaseandPrepReleaseare untouched. Neither is release automation. One reports drift on every pull request, which is what caught the sub-module pins sitting four releases behind (#619). The other is a single command the checklist tells you to run.Controls
Each injection was asserted against the real source before editing. Full suite,
mage compilesandgolangci-lint run ./...all clean.