From eef108edf5c6d0ca3e576da90a920f07e534479c Mon Sep 17 00:00:00 2001 From: nikhil-mittal-165 Date: Thu, 29 Oct 2026 12:34:38 +0530 Subject: [PATCH 1/5] CHANGE @W-00000000@ Migrate npm publishing to Trusted Publishing (OIDC) Replace the long-lived NPM_TOKEN with npm Trusted Publishing, ahead of the Nov 12, 2026 token expiry and npm's bypass-2fa publish deprecation. - publish-to-npm.yml: grant id-token: write, upgrade npm, pass --trusted-publishing to sf-release, drop NPM_TOKEN usage - apply-npm-tag-to-version.yml: use OIDC for dist-tag instead of a token - package.json: remove `npm shrinkwrap` (removed in npm 12) Requires the trusted publisher to be configured on npmjs.com (with "Allow npm dist-tag" enabled) before merging. Co-Authored-By: Claude Sonnet 5.5 --- .../workflows/apply-npm-tag-to-version.yml | 10 ++++++++-- .github/workflows/publish-to-npm.yml | 19 +++++++++++++++---- package.json | 5 ++--- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/.github/workflows/apply-npm-tag-to-version.yml b/.github/workflows/apply-npm-tag-to-version.yml index fb199f4e1..63da75636 100644 --- a/.github/workflows/apply-npm-tag-to-version.yml +++ b/.github/workflows/apply-npm-tag-to-version.yml @@ -18,6 +18,10 @@ on: jobs: publish_package: runs-on: ubuntu-latest + permissions: + # Required for npm Trusted Publishing (OIDC). + id-token: write + contents: read steps: - uses: actions/checkout@v4 @@ -31,8 +35,10 @@ jobs: echo "::error::You did not confirm, so dist-tag not called." exit 1 - - name: Prepare NPM Credentials - run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc + # Managing dist-tags via Trusted Publishing requires a recent npm (>= 11.21.0), and the trusted publisher + # configuration on npmjs.com must have "Allow npm dist-tag" enabled. + - name: Upgrade npm for Trusted Publishing + run: npm install -g npm@latest - name: Apply tag run: | diff --git a/.github/workflows/publish-to-npm.yml b/.github/workflows/publish-to-npm.yml index 6789a971f..7e5d3c883 100644 --- a/.github/workflows/publish-to-npm.yml +++ b/.github/workflows/publish-to-npm.yml @@ -56,11 +56,14 @@ jobs: fi env: INPUTS_GITHUB_TAG: ${{ github.event.release.tag_name || inputs.tag }} - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # Step 2: Publish the tag as a release candidate. publish-rc: needs: verify-candidate-tag runs-on: ubuntu-latest + permissions: + # Required for npm Trusted Publishing (OIDC). + id-token: write + contents: read steps: - uses: actions/checkout@v4 with: @@ -69,6 +72,8 @@ jobs: with: node-version: 'lts/*' - run: npm install && npm run build + # Trusted Publishing requires npm >= 11.5.1, which is newer than the npm bundled with Node LTS. + - run: npm install -g npm@latest - run: npm install -g @salesforce/plugin-release-management - name: NPM release run: | @@ -76,13 +81,13 @@ jobs: --githubtag "$INPUTS_GITHUB_TAG" \ --npmtag "$INPUTS_NPM_TAG" \ --no-install \ - --sign + --sign \ + --trusted-publishing env: INPUTS_GITHUB_TAG: ${{ github.event.release.tag_name || inputs.tag }} INPUTS_NPM_TAG: latest-rc # Publish as a release candidate, so we can do our validations against it. AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}} AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}} - NPM_TOKEN: ${{secrets.NPM_TOKEN}} # Step 3: Run smoke tests against the release candidate. rc-test: needs: publish-rc @@ -126,12 +131,18 @@ jobs: promote-to-latest: needs: rc-test runs-on: ubuntu-latest + permissions: + # Required for npm Trusted Publishing (OIDC). + id-token: write + contents: read steps: - uses: actions/setup-node@v4 with: node-version: 'lts/*' + # Managing dist-tags via Trusted Publishing requires a recent npm (>= 11.21.0), and the trusted publisher + # configuration on npmjs.com must have "Allow npm dist-tag" enabled. + - run: npm install -g npm@latest - run: | - echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc npm dist-tag add @salesforce/plugin-code-analyzer@${{ github.event.release.tag_name || inputs.tag }} latest # Step 5: Create a Pull Request for merging `main` into `dev` create-main2dev-pull-request: diff --git a/package.json b/package.json index c4dfe08be..168ed52fb 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,6 @@ "files": [ "/lib", "/messages", - "/npm-shrinkwrap.json", "/oclif.manifest.json" ], "homepage": "https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/overview", @@ -89,8 +88,8 @@ "repository": "forcedotcom/code-analyzer", "scripts": { "build": "tsc --build tsconfig.json", - "prepack": "rm -rf lib && tsc --build tsconfig.json && oclif manifest && oclif readme && npm shrinkwrap", - "postpack": "rm -f oclif.manifest.json oclif.lock npm-shrinkwrap.json", + "prepack": "rm -rf lib && tsc --build tsconfig.json && oclif manifest && oclif readme", + "postpack": "rm -f oclif.manifest.json oclif.lock", "lint": "eslint ./src --max-warnings 0", "version": "oclif readme && git add README.md", "test": "tsc --build ./test/tsconfig.json --noEmit && vitest run --coverage", From 4bb0d57fc8f02a9fdf603c346370b2d6ade01a37 Mon Sep 17 00:00:00 2001 From: nikhil-mittal-165 Date: Thu, 29 Oct 2026 13:14:02 +0530 Subject: [PATCH 2/5] CHANGE @W-00000000@ Pin npm to 11 and keep shipping npm-shrinkwrap.json npm 12 removed `npm shrinkwrap` and no longer packs npm-shrinkwrap.json, so `npm@latest` would silently drop the pinned dependency tree this plugin ships. - Install npm@11 (>= 11.21.0, which has OIDC dist-tag support) instead of latest - Generate the shrinkwrap with `cp package-lock.json npm-shrinkwrap.json` in prepack; verified byte-identical to `npm shrinkwrap` output and to the shrinkwrap in the published 5.16.0 tarball - Restore the /npm-shrinkwrap.json entry in `files` and its postpack cleanup Co-Authored-By: Claude Sonnet 5.5 --- .github/workflows/apply-npm-tag-to-version.yml | 2 +- .github/workflows/publish-to-npm.yml | 6 ++++-- package.json | 5 +++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/apply-npm-tag-to-version.yml b/.github/workflows/apply-npm-tag-to-version.yml index 63da75636..1b191f627 100644 --- a/.github/workflows/apply-npm-tag-to-version.yml +++ b/.github/workflows/apply-npm-tag-to-version.yml @@ -38,7 +38,7 @@ jobs: # Managing dist-tags via Trusted Publishing requires a recent npm (>= 11.21.0), and the trusted publisher # configuration on npmjs.com must have "Allow npm dist-tag" enabled. - name: Upgrade npm for Trusted Publishing - run: npm install -g npm@latest + run: npm install -g npm@11 - name: Apply tag run: | diff --git a/.github/workflows/publish-to-npm.yml b/.github/workflows/publish-to-npm.yml index 7e5d3c883..e272ea752 100644 --- a/.github/workflows/publish-to-npm.yml +++ b/.github/workflows/publish-to-npm.yml @@ -73,7 +73,9 @@ jobs: node-version: 'lts/*' - run: npm install && npm run build # Trusted Publishing requires npm >= 11.5.1, which is newer than the npm bundled with Node LTS. - - run: npm install -g npm@latest + # Pinned to the npm 11 line (not latest): npm 12 removed `npm shrinkwrap` and no longer packs + # npm-shrinkwrap.json, which this package ships (see `prepack` in package.json). + - run: npm install -g npm@11 - run: npm install -g @salesforce/plugin-release-management - name: NPM release run: | @@ -141,7 +143,7 @@ jobs: node-version: 'lts/*' # Managing dist-tags via Trusted Publishing requires a recent npm (>= 11.21.0), and the trusted publisher # configuration on npmjs.com must have "Allow npm dist-tag" enabled. - - run: npm install -g npm@latest + - run: npm install -g npm@11 - run: | npm dist-tag add @salesforce/plugin-code-analyzer@${{ github.event.release.tag_name || inputs.tag }} latest # Step 5: Create a Pull Request for merging `main` into `dev` diff --git a/package.json b/package.json index 168ed52fb..06baad33e 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "files": [ "/lib", "/messages", + "/npm-shrinkwrap.json", "/oclif.manifest.json" ], "homepage": "https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/overview", @@ -88,8 +89,8 @@ "repository": "forcedotcom/code-analyzer", "scripts": { "build": "tsc --build tsconfig.json", - "prepack": "rm -rf lib && tsc --build tsconfig.json && oclif manifest && oclif readme", - "postpack": "rm -f oclif.manifest.json oclif.lock", + "prepack": "rm -rf lib && tsc --build tsconfig.json && oclif manifest && oclif readme && cp package-lock.json npm-shrinkwrap.json", + "postpack": "rm -f oclif.manifest.json oclif.lock npm-shrinkwrap.json", "lint": "eslint ./src --max-warnings 0", "version": "oclif readme && git add README.md", "test": "tsc --build ./test/tsconfig.json --noEmit && vitest run --coverage", From 3b67b7aa230fb2e074aa5854cf524ce6a8c677f3 Mon Sep 17 00:00:00 2001 From: nikhil-mittal-165 Date: Thu, 29 Oct 2026 13:55:36 +0530 Subject: [PATCH 3/5] CHANGE @W-00000000@ Restore original npm shrinkwrap in prepack With npm pinned to 11, `npm shrinkwrap` still works (verified on 11.21.1: output is byte-identical to the shrinkwrap in published 5.16.0), so the `cp package-lock.json npm-shrinkwrap.json` workaround is unnecessary. package.json is now unchanged from dev. Co-Authored-By: Claude Opus 5.5 (1M context) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 06baad33e..c4dfe08be 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "repository": "forcedotcom/code-analyzer", "scripts": { "build": "tsc --build tsconfig.json", - "prepack": "rm -rf lib && tsc --build tsconfig.json && oclif manifest && oclif readme && cp package-lock.json npm-shrinkwrap.json", + "prepack": "rm -rf lib && tsc --build tsconfig.json && oclif manifest && oclif readme && npm shrinkwrap", "postpack": "rm -f oclif.manifest.json oclif.lock npm-shrinkwrap.json", "lint": "eslint ./src --max-warnings 0", "version": "oclif readme && git add README.md", From 0ca72ddf439597d37e02f1c470fa13001c94f05e Mon Sep 17 00:00:00 2001 From: nikhil-mittal-165 Date: Thu, 29 Oct 2026 14:02:34 +0530 Subject: [PATCH 4/5] CHANGE @W-24708955@ Retrigger PR checks with work item Co-Authored-By: Claude Opus 5.5 (1M context) From 284c964574fcd679ea011b1006c528df82077a50 Mon Sep 17 00:00:00 2001 From: nikhil-mittal-165 Date: Thu, 29 Oct 2026 14:07:47 +0530 Subject: [PATCH 5/5] FIX @W-24708955@ Pass workflow inputs via env to avoid shell injection Address SAST rule github-actions.security.run-shell-injection: move github.event.inputs / release tag values out of direct ${{ }} interpolation in run: steps and into env vars, quoted at use. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/apply-npm-tag-to-version.yml | 9 +++++++-- .github/workflows/publish-to-npm.yml | 10 +++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.github/workflows/apply-npm-tag-to-version.yml b/.github/workflows/apply-npm-tag-to-version.yml index 1b191f627..b0a46aab4 100644 --- a/.github/workflows/apply-npm-tag-to-version.yml +++ b/.github/workflows/apply-npm-tag-to-version.yml @@ -41,7 +41,12 @@ jobs: run: npm install -g npm@11 - name: Apply tag + # Pass user-supplied inputs via the environment rather than direct ${{ }} interpolation, so they are + # treated as data and cannot inject shell commands. + env: + INPUTS_TAG_NAME: ${{ github.event.inputs.tag_name }} + INPUTS_VERSION: ${{ github.event.inputs.version }} run: | - echo "You have confirmed that using this action is only recommended for emergency rollback situations and that you are responsible for manually applying the ${{ github.event.inputs.tag_name }} tag to @salesforce/plugin-code-analyzer@${{ github.event.inputs.version }}." + echo "You have confirmed that using this action is only recommended for emergency rollback situations and that you are responsible for manually applying the ${INPUTS_TAG_NAME} tag to @salesforce/plugin-code-analyzer@${INPUTS_VERSION}." echo "Applying tag..." - npm dist-tag add @salesforce/plugin-code-analyzer@${{ github.event.inputs.version }} ${{ github.event.inputs.tag_name }} + npm dist-tag add "@salesforce/plugin-code-analyzer@${INPUTS_VERSION}" "${INPUTS_TAG_NAME}" diff --git a/.github/workflows/publish-to-npm.yml b/.github/workflows/publish-to-npm.yml index e272ea752..92291fe18 100644 --- a/.github/workflows/publish-to-npm.yml +++ b/.github/workflows/publish-to-npm.yml @@ -42,8 +42,10 @@ jobs: # Verify that the tag is of the format "vX.Y.Z", where the X, Y, and Z exactly match the corresponding values in # `package.json`'s version property. - name: Compare tag to package.json + env: + INPUTS_GITHUB_TAG: ${{ github.event.release.tag_name || inputs.tag }} run: | - TAG=${{ github.event.release.tag_name || inputs.tag }} + TAG="$INPUTS_GITHUB_TAG" PACKAGE_VERSION=v`cat package.json | jq '.version' | xargs` [[ ${TAG} == ${PACKAGE_VERSION} ]] || (echo "Tag name must match package.json version, prefixed by lowercase v" && exit 1) - name: Check if this version number is already used on NPM @@ -144,8 +146,10 @@ jobs: # Managing dist-tags via Trusted Publishing requires a recent npm (>= 11.21.0), and the trusted publisher # configuration on npmjs.com must have "Allow npm dist-tag" enabled. - run: npm install -g npm@11 - - run: | - npm dist-tag add @salesforce/plugin-code-analyzer@${{ github.event.release.tag_name || inputs.tag }} latest + - env: + INPUTS_GITHUB_TAG: ${{ github.event.release.tag_name || inputs.tag }} + run: | + npm dist-tag add "@salesforce/plugin-code-analyzer@${INPUTS_GITHUB_TAG}" latest # Step 5: Create a Pull Request for merging `main` into `dev` create-main2dev-pull-request: needs: promote-to-latest