From e65a099b912851a89913086bb52fcc5885d0f7fb Mon Sep 17 00:00:00 2001 From: jstet Date: Thu, 24 Sep 2026 17:45:03 +0200 Subject: [PATCH] ci(release): never overwrite a published release asset Consumers pin release-asset checksums (formulaid verifies the skill archive's SHA-256), so replacing an asset under an existing tag would break them. Drop --clobber; the upload step now fails if any asset already exists on the release. A manual run still attaches assets an older release is missing. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/release-assets.yml | 19 ++++++++++++++++--- README.md | 3 ++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-assets.yml b/.github/workflows/release-assets.yml index e5b1be4..ce17705 100644 --- a/.github/workflows/release-assets.yml +++ b/.github/workflows/release-assets.yml @@ -14,7 +14,12 @@ name: Attach release assets # v. The job fails if the tag and package.json disagree. # # Runs when a release is published. Run it manually with an existing tag to -# (re)attach assets to an older release; --clobber replaces them. +# attach assets an older release is missing. +# +# Published assets are immutable: consumers pin their checksums (formulaid +# verifies the skill archive's SHA-256), so an asset that already exists is +# never replaced and the job fails instead. To ship a fix, publish a new +# version. on: release: @@ -73,5 +78,13 @@ jobs: node -e "import('@correlaid/formtransform').then((m) => { if (!m.XLSFormToTSVConverter) process.exit(1); })" npx --no-install formtransform --help >/dev/null - - name: Upload to the release - run: gh release upload "$TAG" assets/* --clobber + - name: Upload to the release (never overwrite) + run: | + existing=$(gh release view "$TAG" --json assets --jq '.assets[].name') + for f in assets/*; do + if grep -qxF "$(basename "$f")" <<<"$existing"; then + echo "::error::$(basename "$f") already exists on $TAG. Published assets are immutable; publish a new version instead." + exit 1 + fi + done + gh release upload "$TAG" assets/* diff --git a/README.md b/README.md index 9990399..6f37d6a 100644 --- a/README.md +++ b/README.md @@ -211,7 +211,8 @@ npm run bless Publishing the tag builds the `schematron-worker` image (`worker-image.yml`). Publishing the release attaches the package tarball and the skill archive (`release-assets.yml`). That job fails if the tag and -`package.json` disagree. +`package.json` disagree, and it never replaces an asset that already exists: +consumers pin the checksums, so a fix ships as a new version. ## Documentation