From 85f4f4dfcd3b571b9377f5e7c724755441d70543 Mon Sep 17 00:00:00 2001 From: Adhik Joshi Date: Wed, 9 Sep 2026 23:44:05 +0530 Subject: [PATCH] Let a release retry overwrite the assets it already uploaded MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The v0.2.0 retry got past the tap credentials and then died on the upload: upload failed error=POST .../releases/385736691/assets?name=modelslab_0.2.0_linux_arm64.tar.gz: 422 Validation Failed [{Resource:ReleaseAsset Field:name Code:already_exists}] ...once for each of the 11 assets the first, half-failed run had already attached, and npm and PyPI were skipped again behind it. `release.mode: replace` was the wrong lever. It governs the release NOTES; it says nothing about artifacts. `replace_existing_artifacts` is the half that overwrites them, and without it no retry of a run that got as far as uploading can ever succeed — which is exactly the situation the retry exists for. Verified locally end to end against a snapshot build: goreleaser check passes, 6 binaries collected (the count the workflow asserts), packaging/npm/build.mjs produces the 6 platform packages plus the entry package pinning them, and packaging/pypi/build.py produces the 6 wheels, all stamped 0.2.0. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01QgkQePXPha8ShvoBerrVXL --- .goreleaser.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index d8d2e79..8d85f0d 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -38,10 +38,15 @@ checksum: name_template: "checksums.txt" release: - # Re-running a release must be safe. The default `keep-existing` leaves a - # half-published release from a failed run in place, so the retry cannot - # correct it; `replace` makes the tag's assets match whatever this run built. + # Re-running a release must be safe. + # + # `mode` governs the release NOTES only — it does nothing about artifacts, and + # the v0.2.0 retry died proving it: every upload came back + # `422 already_exists` against the assets the first, half-failed run had + # already attached. replace_existing_artifacts is the half that actually + # overwrites them. mode: replace + replace_existing_artifacts: true snapshot: version_template: "{{ incpatch .Version }}-next"