Summary
make generate rewrites the embedded swaggerSpec block in most committed .gen.go files depending on which Go toolchain runs it, because the spec is deflate-compressed at generation time and compress/flate output changed in Go 1.27. The fixtures currently committed on main were produced by Go 1.27, while go.mod declares go 1.25.0. Anyone regenerating with the declared toolchain gets ~58 files of base64-only diffs and either commits noise or hand-reverts it.
Evidence
Measured on internal/test/servers/strict/stdhttp/server.gen.go at 2679cec6 (current main), regenerating the fixture and hashing the swaggerSpec block:
| Toolchain |
Blob matches committed file |
go1.25.0 (the go.mod directive) |
no |
| go1.25.9 |
no |
| go1.26.0 |
no |
| go1.26.2 |
no |
| go1.27.0 |
yes, byte-identical |
All 1.25.x and 1.26.x toolchains produce the same blob as each other. Decoding both blobs (raw deflate) yields identical spec content, so the difference is only the compressor.
The committed blobs date from 89284708 (2026-08-27, "chore(deps): update oapi-codegen/actions action to v0.9.2"), which touched 58 generated files with base64-only changes while go.mod already said go 1.25.0. That commit's regeneration ran on a 1.27 toolchain.
Proposal
- Regenerate everything once with the toolchain pinned to the
go.mod directive and commit it as a standalone chore, so feature PRs stop carrying base64 churn:
GOTOOLCHAIN=go1.25.0 make generate
- Make the pin the convention: have the
generate Makefile target set GOTOOLCHAIN from the go directive (or document it in CONTRIBUTING.md), so contributors on newer local toolchains reproduce the committed bytes.
- Check whether anything in CI (the shared
oapi-codegen/actions workflow or a renovate post-upgrade step) regenerates and commits fixtures with a floating toolchain. If so, pin it the same way, otherwise the blobs will flip back on the next automated regen.
Notes
- Any PR opened before the chore lands will show the base64 churn if its author regenerated with 1.25/1.26. Reviewers can ignore hunks that are only
swaggerSpec lines, but it's easy to miss a real change hidden among them.
- Alternative: make the embedded spec toolchain-independent (e.g. store it uncompressed, or compress with a fixed, vendored encoder). That's a larger change to
pkg/codegen/templates/inline.tmpl and the runtime decode path, so the pin seems like the pragmatic first step.
Summary
make generaterewrites the embeddedswaggerSpecblock in most committed.gen.gofiles depending on which Go toolchain runs it, because the spec is deflate-compressed at generation time andcompress/flateoutput changed in Go 1.27. The fixtures currently committed onmainwere produced by Go 1.27, whilego.moddeclaresgo 1.25.0. Anyone regenerating with the declared toolchain gets ~58 files of base64-only diffs and either commits noise or hand-reverts it.Evidence
Measured on
internal/test/servers/strict/stdhttp/server.gen.goat2679cec6(currentmain), regenerating the fixture and hashing theswaggerSpecblock:go.moddirective)All 1.25.x and 1.26.x toolchains produce the same blob as each other. Decoding both blobs (raw deflate) yields identical spec content, so the difference is only the compressor.
The committed blobs date from
89284708(2026-08-27, "chore(deps): update oapi-codegen/actions action to v0.9.2"), which touched 58 generated files with base64-only changes whilego.modalready saidgo 1.25.0. That commit's regeneration ran on a 1.27 toolchain.Proposal
go.moddirective and commit it as a standalone chore, so feature PRs stop carrying base64 churn:generateMakefile target setGOTOOLCHAINfrom thegodirective (or document it inCONTRIBUTING.md), so contributors on newer local toolchains reproduce the committed bytes.oapi-codegen/actionsworkflow or a renovate post-upgrade step) regenerates and commits fixtures with a floating toolchain. If so, pin it the same way, otherwise the blobs will flip back on the next automated regen.Notes
swaggerSpeclines, but it's easy to miss a real change hidden among them.pkg/codegen/templates/inline.tmpland the runtime decode path, so the pin seems like the pragmatic first step.