fix(release): make archives reproducible so winget hashes match - #121
Merged
Conversation
The release workflow runs GoReleaser twice (core with --skip=winget, then best-effort winget-only), both with --clean. The second run rebuilds from scratch, and since archive members carried build/checkout mtimes the rebuilt archives hashed differently than the ones the first run had already uploaded to the GitHub release. The winget manifest is generated by the second run, so it shipped a hash no published asset matched -- microsoft/winget-pkgs#410145 was rejected with Error-Hash-Mismatch for 0.1.31. Pin the binary timestamp (mod_timestamp), add -trimpath, and pin the mtime of every archive member including the default LICENSE/README globs. Verified: two consecutive `goreleaser release --snapshot --clean` runs now produce byte-identical archives for all five targets; before this change the same two runs produced different hashes. Also migrates format/format_overrides.format to the plural `formats` form (singular deprecated since v2.6).
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #121 +/- ##
==========================================
+ Coverage 37.62% 37.71% +0.09%
==========================================
Files 28 28
Lines 3216 3216
==========================================
+ Hits 1210 1213 +3
+ Misses 1917 1913 -4
- Partials 89 90 +1 🚀 New features to boost your workflow:
|
7 tasks
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.
Problem
microsoft/winget-pkgs#410145(0.1.31) was rejected withError-Hash-Mismatch:The published asset is fine — the manifest's hash was wrong.
release.ymlruns GoReleaser twice, both with--clean: step 1 builds and uploads the release assets (--skip=winget), step 2 rebuilds everything from scratch to publish winget only (WT_WINGET_ONLY=1, release upload disabled). Archive members carried build/checkout mtimes, so step 2's rebuild produced byte-different archives. The winget manifest got step 2's hash while the release kept step 1's bytes.This started with 5c616e2 (the two-step split, 2026-07-08): 0.1.29 predates it and its manifest hash matches; 0.1.31 does not.
Fix
builds:-trimpathandmod_timestamp: '{{ .CommitTimestamp }}'archives:builds_info.mtimeplus explicitLICENSE*/README*entries with pinnedmtime— the default globs carried checkout time and mattered as much as the binaryformat/format_overrides.formatto pluralformats(singular deprecated since v2.6)Verification
Two consecutive
goreleaser release --snapshot --cleanruns:f9d17d80…61b22038…4226751f…4226751f…All five archives byte-identical after the change.
goreleaser checkpasses (thebrewsdeprecation warning is pre-existing).The 0.1.31 manifest hash was corrected directly on the winget PR branch; this change prevents a recurrence.