From 185179ddd69af2984dfdbb004636e8526ca560a8 Mon Sep 17 00:00:00 2001 From: Konard Date: Fri, 28 Aug 2026 17:33:29 +0700 Subject: [PATCH] fix(js): give npm provenance a repository.url to verify against Trusted publishing (OIDC) makes npm attach a provenance attestation to every publish, and the registry then cross-checks the attestation's source repo against "repository.url" in the manifest. js/package.json carried no repository field at all, so the check compared "link-foundation/links-notation" against "" and rejected the upload: npm error code E422 Error verifying sigstore provenance bundle: Failed to validate repository information: package.json: "repository.url" is "" This is deterministic, which is why re-running the job never helped. It only surfaced now because 0.13.0 and earlier were token publishes, which attach no provenance and so never consulted the field. The repository/bugs/homepage shape is copied from link-foundation/js-ai-driven-development-pipeline-template, which already carries it. Two smaller fixes in the same publish step: - The step piped npm output through "tee publish.log" inside the package directory, so npm built the tarball with the log inside it; 0.15.0's tarball shipped a 0-byte publish.log. The log now goes to RUNNER_TEMP. - The failure handler only explained ENEEDAUTH/E401/E403, so this E422 failed with no diagnostic at all. Added a provenance branch that names the mismatched repository.url. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01W35mjrg7zi5Y8TW17EWduq --- .github/workflows/js.yml | 10 ++++++++-- js/package.json | 8 ++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/js.yml b/.github/workflows/js.yml index 0fbd359..dfc1500 100644 --- a/.github/workflows/js.yml +++ b/.github/workflows/js.yml @@ -216,10 +216,16 @@ jobs: echo "npm credential: NPM_TOKEN absent, relying on OIDC trusted publishing" fi - if ! npm publish --access public 2>&1 | tee publish.log; then - if grep -q 'ENEEDAUTH\|E401\|E403' publish.log; then + # Keep the log outside the package directory: npm builds the tarball + # from the working tree, so a log written here ships inside it. + PUBLISH_LOG="$RUNNER_TEMP/publish.log" + if ! npm publish --access public 2>&1 | tee "$PUBLISH_LOG"; then + if grep -q 'ENEEDAUTH\|E401\|E403' "$PUBLISH_LOG"; then echo "::error::npm rejected the credentials. Either configure trusted publishing for ${{ steps.version-check.outputs.name }} on npmjs.com or set the NPM_TOKEN secret." fi + if grep -q 'E422\|provenance' "$PUBLISH_LOG"; then + echo "::error::npm rejected the provenance attestation. Trusted publishing signs the package with this repository's identity, so package.json must carry a matching \"repository.url\" (https://github.com/${{ github.repository }})." + fi echo "published=failed" >> "$GITHUB_OUTPUT" exit 1 fi diff --git a/js/package.json b/js/package.json index bd0d6a3..3933317 100644 --- a/js/package.json +++ b/js/package.json @@ -23,6 +23,14 @@ ], "author": "", "license": "Unlicense", + "repository": { + "type": "git", + "url": "git+https://github.com/link-foundation/links-notation.git" + }, + "bugs": { + "url": "https://github.com/link-foundation/links-notation/issues" + }, + "homepage": "https://github.com/link-foundation/links-notation#readme", "devDependencies": { "bun-types": "^1.3.14", "eslint": "^10.8.1",