fix(artifacts): resolve the snapshot existence check against JFrog - #178
Open
senthanal wants to merge 1 commit into
Open
fix(artifacts): resolve the snapshot existence check against JFrog#178senthanal wants to merge 1 commit into
senthanal wants to merge 1 commit into
Conversation
PR snapshots are versioned `0.0.0-<branch>-<prNumber>`, which is constant for the lifetime of a PR, so every push after the first republishes an identical version. NxProject.deleteArtifact compensates by unpublishing the version before publishing it again, but its guard never let that happen. packageExists ran `npm show <pkg> --json` with no cwd and no --registry. From the repository root that resolves against the public registry, where the private scope does not exist, so the lookup 404'd, the guard read the 404 as "version absent", the unpublish was skipped, and npm publish then PUT a version that was already on JFrog — which Artifactory rejects with 403 Forbidden. The check now pins --registry to the JFrog URL the publish and unpublish already target, and runs in the dist directory whose .npmrc carries the credentials for it. The dist bootstrap in deleteArtifact moved above the check so the ONLY_DELETE_ARTIFACTS path is authenticated too. A second defect kept this invisible: the catch reported every failure as "not found", so an auth error or a registry outage produced the same silent skip and the same 403 one step later. Only a 404 now counts as absent; anything else fails the job with the underlying cause. Observed on cplace-dataciders-portfolio-management-fe PR #46, where the snapshot job succeeded once on 2026-08-06 and then failed identically on every subsequent push. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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
publish-pr-snapshotfails with403 Forbiddenon every push to a PR after the first one:The version being published already exists on JFrog, and Artifactory rejects redeploy.
Root cause
Utils.getPRVersion()builds the suffix from branch name + PR number only — no timestamp — so the version is constant for the lifetime of a PR, unlikegetUniqueSnapshotIdentifier().NxProject.deleteArtifact()is what makes that workable: it unpublishes the version before republishing it. Its guard never let that happen.packageExists()ran:No
cwd, no--registry. Every sibling npm call in the file passes the dist directory (npm unpublishin the same method,Utils.getAllSnapshotVersionsOfPackage); this one didn't, so it executed at the repository root and resolved against the public registry:404 →
catch→return false→ unpublish skipped → publish collides → 403.The same two log lines appear in the job that succeeded, on the PR's first push. The check has always resolved against the wrong registry; it was harmless only while the version genuinely did not exist yet.
A second defect kept it invisible: the
catchreported every failure as "not found". An auth failure or a registry outage produces the identical silent skip and the identical 403 one step later.Fix
packageExists()pins--registrytogetJfrogUrl()— the same registrynpm publishandnpm unpublishalready target — and runs in the dist directory, whose.npmrccarries the credentials for it.deleteArtifact()moved above the existence check, so theONLY_DELETE_ARTIFACTSpath is authenticated too. Previously that path wrote the.npmrcafter the check that needed it.Impact
Every product repo that pushes a second snapshot to the same PR hits this. Observed on
cplace-dataciders-portfolio-management-fePR #46: snapshot job green on 2026-08-06, then 403 on 08-13, 08-16, 08-17 and 08-18 — once per push, deterministic.Note that already-stuck PRs need their existing snapshot version deleted once by hand; this fix stops the next one from getting stuck, it doesn't retroactively clear one.
Tests
Five tests added around
deleteArtifact— there were none before:npm unpublishrunsnpm test: 51 passed, up from 46, with the failure count unchanged at 8 — those 8 fail identically on unmodifiedrelease/26.1and are unrelated (2 innx-project.test.tsaroundgetMarkdownLinkand e2eisPublishable, 6 inupmerge).npx tsc --noEmitandprettier --checkboth clean.🤖 Generated with Claude Code