Skip to content

ci(binaries): never replace an archive that is already published - #68

Merged
vyncint merged 1 commit into
mainfrom
immutable-release-assets
Aug 23, 2026
Merged

ci(binaries): never replace an archive that is already published#68
vyncint merged 1 commit into
mainfrom
immutable-release-assets

Conversation

@vyncint

@vyncint vyncint commented Aug 23, 2026

Copy link
Copy Markdown
Owner

Found by re-running binaries.yml to test the Homebrew token: the formula job reported "tap updated" where nothing should have changed, and the diff was four checksums.

What was wrong

The upload used --clobber, so re-running the artifact build for an existing tag rebuilt and overwrote the archives. Rust builds are not bit-for-bit reproducible, so the replacements had different checksums:

-      sha256 "1c61f6f3e9df5d6d647a86a26a0f92e0a7ef8e4ce15d2304919ad85e4078e205"
+      sha256 "56c252c1adf1b06a4b47ba1ddd5bee80c6e9d037e86c70f2a05033abb31455d1"
   … and three more

Every checksum anyone had recorded became wrong — including the formula's, and including one somebody had written down to verify a download with. A published artifact should be immutable, and this made it anything but.

The irony is that the re-runnability I added two PRs ago is what made it reachable.

The fix

Upload only what is absent:

asset already on the release action
…-x86_64-unknown-linux-musl.tar.gz yes skip
…-x86_64-pc-windows-msvc.zip no upload
….tar.gz.sha256 no upload

That is precisely the case the workflow was built for — the Windows archive that failed to build the first time was exactly a missing asset needing filling in. Replacing a genuinely corrupt one now means deleting it first, and that friction is deliberate.

Current state is consistent

The tap and the release agree right now, verified by installing:

$ brew install vyncint/tap/mossaic
$ mossaic-art --version
mossaic-art 0.6.2

The upload clobbered, so re-running the artifact build for an existing
tag rebuilt and overwrote the archives. Rust builds are not bit-for-bit
reproducible, so the replacements had different checksums -- and every
checksum anyone had recorded became wrong, including the Homebrew
formula's and including one somebody had written down to verify a
download with.

Found by re-running it: the formula job reported 'tap updated' where
nothing should have changed, and the diff was four checksums.

A re-run now uploads what is missing and leaves what is there alone,
which is the case this workflow was built for -- the Windows archive that
failed to build first time was exactly it. Replacing a genuinely corrupt
asset means deleting it first, and that friction is deliberate: a
published artifact should be immutable.

Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com>
@vyncint
vyncint merged commit 25bc7c2 into main Aug 23, 2026
11 checks passed
@vyncint
vyncint deleted the immutable-release-assets branch August 23, 2026 08:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant