release: stop running go mod tidy at release time, assert tidiness in CI - #642
Merged
Conversation
…in CI
goreleaser ran `go mod tidy` as a before-hook inside the release container.
It took v0.63.8 down: the hook spent 4m49s walking the module graph and then
failed when proxy.golang.org returned HTTP/2 INTERNAL_ERROR on six unrelated
fetches. `go mod tidy` resolves the test dependencies of dependencies too, so
it touches far more of the network than a build needs, on the one path where
a flake costs a release.
The hook was also unsound in a quieter way. It MUTATES go.mod/go.sum, so a
drifted module set would have been silently rewritten inside the container
and the published binaries built against something no CI job had ever
compiled. A release-time rewrite is not a check.
Drop it — the config already skips tests here on the reasoning that the tag
is on a green commit, and the same argument applies.
Nothing verified module tidiness before this: no workflow, no Makefile
target. So the `lint` job gains a `go mod tidy` + `git diff --exit-code`
step, which fails the PR that introduces drift instead of papering over it
at tag time. main is already tidy, so the gate is green on landing.
Verified with the real toolchain, not by reading it:
* `goreleaser build --snapshot` with a deliberately failing before-hook
aborts at "running before hooks" in 0s, so hooks do execute in that mode;
with `hooks: []` the stage never appears and the run goes straight from
snapshotting to building. No default hook takes its place.
* `goreleaser check` validates the config.
* The CI gate passes on main unchanged, and fails with exit 1 (naming
go.mod) against a commit carrying a deliberately untidy require line.
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.
What broke
The v0.63.8 release failed in goreleaser's
beforehook:Six unrelated module fetches got HTTP/2
INTERNAL_ERRORfromproxy.golang.org—gomlx, fourgo-sitter-forestgrammars,tree-sitter-protobuf. A transient proxy flake, but it took the release down after ~5 minutes, and nothing had been published yet.Why the hook has to go, not just get a retry
go mod tidyresolves the test dependencies of the dependencies — that's why the failure log is full of... tested by ... .test imports ...chains. It touches far more of the network than building the release needs, on the one path where a flake costs a release.It is also unsound in a quieter way: it mutates
go.mod/go.suminside the release container. A drifted module set would have been silently rewritten at tag time and the published binaries built against something no CI job had ever compiled. A rewrite is not a check.The config already skips tests in this hook on the reasoning that "the tag is already on a green commit". The same argument applies here.
Correction to what I said when I proposed this
I claimed CI already verified tidiness. It does not — there is no
go mod tidycheck in any workflow or in the Makefile. This release-time hook was the only thing exercising it, and it did so by rewriting rather than failing. So dropping it alone would have removed the last (bad) tidy pass.This PR therefore does both halves:
go mod tidybefore-hook from.goreleaser.ymlgo.mod is tidystep to thelintjob:go mod tidythengit diff --exit-code go.mod go.sum, which fails the PR that introduces driftmainis already tidy, so the new gate is green on landing.Verification (real toolchain, not by reading it)
goreleaser build --snapshotwith a deliberately failing before-hook aborts atrunning before hooksin 0s — proving hooks do execute in that mode.hooks: [], that stage never appears; the run goes straight fromsnapshottingtobuilding binaries. No default hook silently takes its place.goreleaser checkvalidates the config.mainunchanged, and exits 1 naminggo.modwhen run against a commit carrying a deliberately untidyrequireline.Not included
Re-running the failed v0.63.8 release — that's yours to trigger. State is clean for it: no v0.63.8 GitHub release was created, and the tap is untouched.