Skip to content

ci(jfrog): refuse to overwrite a published version - #76

Merged
BernardJen merged 1 commit into
mainfrom
ci/overwrite-guard
Sep 3, 2026
Merged

BernardJen merged 1 commit into
mainfrom
ci/overwrite-guard

Conversation

@BernardJen

Copy link
Copy Markdown
Contributor

Part of the JFrog evaluation (Lab271/labs-jfrog-poc#4). Generalises the guard already shipped on the Cargo pilot in Lab271/sqlite-rs#684.

Why

lab-npm-dev-local and lab-npm-prod-local are mutable. blackedOut: false, and no repository immutability setting exists on an Artifactory local repo — all 64 config fields were checked. Re-publishing a version overwrites the bytes silently, with no error, including a version already promoted with status Released.

That is not hypothetical. During the evaluation a promoted artifact was overwritten exactly this way: the bytes changed 17 minutes after promotion and the build-info was left pointing at a digest that no longer existed in the repository.

For npm it also breaks consumers rather than merely confusing them — npm ci verifies the lockfile's integrity hash, so anyone pinning the overwritten version gets an integrity mismatch.

Why it fails rather than skips

The Cargo pilot's equivalent guard warns and skips, because that job runs on every push. This one only runs from a v*.*.* tag, so an existing version means the tag was moved or re-cut. Continuing would either overwrite released bytes or promote a build whose artifact someone else published — both worse than a red run.

What this is not

It is a convention, not an enforced boundary. Repository immutability is the real fix and needs platform admin we do not have (Lab271/labs-jfrog-poc#4). Anything holding the CI token can still overwrite by calling Artifactory directly; this only stops the accident that actually happened.

Verification

The check is a jf rt curl against /api/storage/... for the exact tarball path, confirmed against the live repository layout (lab-npm-prod-local/slidecue/-/slidecue-0.7.4.tgz). Workflow YAML parses. The guard cannot run on a PR — this workflow is tag-triggered — so it is exercised on the next release.

🤖 Generated with Claude Code

lab-npm-*-local are mutable - blackedOut is false and no repository
immutability setting exists on an Artifactory local repo, all 64 config fields
checked. Re-publishing a version overwrites the bytes silently, including a
version already promoted with status Released. That happened during the
evaluation: a promoted artifact's bytes changed 17 minutes after promotion and
the build-info was left pointing at a digest no longer in the repository.

For npm it breaks consumers rather than merely confusing them, since npm ci
verifies the lockfile integrity hash.

Fails rather than skips, unlike the Cargo pilot's equivalent guard: this job
only runs from a version tag, so an existing version means the tag was moved or
re-cut, and continuing would either overwrite released bytes or promote a build
whose artifact someone else published.

This is a convention, not an enforced boundary. Repository immutability is the
real fix and needs platform admin (Lab271/labs-jfrog-poc#4).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@BernardJen
BernardJen merged commit 5233f9c into main Sep 3, 2026
1 check passed
@BernardJen
BernardJen deleted the ci/overwrite-guard branch September 3, 2026 21:31
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