From 80731ca347ab491703d50f26558382034cfe185c Mon Sep 17 00:00:00 2001 From: Matsu Date: Tue, 15 Sep 2026 12:59:22 +0300 Subject: [PATCH] ci: Bypass safe-chain proxy on pnpm publish (#38700) --- .github/workflows/release-publish.yml | 9 ++- .../util-probe-npm-oidc-exchange.yml | 81 ++++++++++++++++++- 2 files changed, 85 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml index 795b07220b3..a900d0fc9ee 100644 --- a/.github/workflows/release-publish.yml +++ b/.github/workflows/release-publish.yml @@ -68,8 +68,8 @@ jobs: - name: Dry-run publishing run: | - pnpm --filter n8n publish --no-git-checks --dry-run - pnpm publish -r --filter '!n8n' --no-git-checks --dry-run + "$PNPM_HOME/pnpm" --filter n8n publish --no-git-checks --dry-run + "$PNPM_HOME/pnpm" publish -r --filter '!n8n' --no-git-checks --dry-run - name: Pre publishing changes run: | @@ -90,13 +90,14 @@ jobs: if [[ "$PUBLISH_TAG" =~ ^v?[0-9] ]]; then PUBLISH_TAG="release-${PUBLISH_TAG}" fi - pnpm publish -r --filter '!n8n' --publish-branch "$PUBLISH_BRANCH" --access public --tag "$PUBLISH_TAG" --no-git-checks + "$PNPM_HOME/pnpm" publish -r --filter '!n8n' --publish-branch "$PUBLISH_BRANCH" --access public --tag "$PUBLISH_TAG" --no-git-checks # If we don't use the --tag rc, all releases will default to "latest". - name: Publish n8n to NPM with rc tag env: PUBLISH_BRANCH: ${{ github.event.pull_request.base.ref }} - run: pnpm --filter n8n publish --publish-branch "$PUBLISH_BRANCH" --access public --tag rc --no-git-checks + run: | + "$PNPM_HOME/pnpm" --filter n8n publish --publish-branch "$PUBLISH_BRANCH" --access public --tag rc --no-git-checks - name: Cleanup rc tag run: npm dist-tag rm n8n rc diff --git a/.github/workflows/util-probe-npm-oidc-exchange.yml b/.github/workflows/util-probe-npm-oidc-exchange.yml index bcbef299f05..5720f145f72 100644 --- a/.github/workflows/util-probe-npm-oidc-exchange.yml +++ b/.github/workflows/util-probe-npm-oidc-exchange.yml @@ -13,14 +13,68 @@ permissions: {} jobs: probe: - name: Probe npm OIDC exchange + name: Probe npm OIDC exchange (${{ matrix.name }}) runs-on: ubuntu-latest environment: npm permissions: id-token: write + strategy: + fail-fast: false + matrix: + include: + - name: pnpm 12 + safe_chain: false + bypass_safe_chain: false + - name: pnpm 12 with SafeChain + safe_chain: true + bypass_safe_chain: false + - name: pnpm 12 with SafeChain bypass + safe_chain: true + bypass_safe_chain: true env: PACKAGE_NAME: ${{ inputs.package-name }} steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Set up Node.js + if: matrix.safe_chain == false + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + with: + node-version: '26.5.1' + + - name: Resolve pnpm version + id: pnpm-version + if: matrix.safe_chain == false + run: node .github/scripts/resolve-pnpm-version.mjs + + - name: Set up raw pnpm + if: matrix.safe_chain == false + uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0 + with: + install: false + version: ${{ steps.pnpm-version.outputs.version }} + + - name: Install dependencies without SafeChain + if: matrix.safe_chain == false + run: pnpm install --frozen-lockfile + + - name: Set up pnpm with SafeChain + if: matrix.safe_chain == true + uses: ./.github/actions/setup-nodejs + with: + build-command: '' + + - name: Verify pnpm version for publishing + shell: bash + run: | + if [ "$(pnpm --version)" != '12.3.4' ]; then + echo '::error::Expected pnpm 12.3.4 for publishing.' + exit 1 + fi + - name: Exchange GitHub OIDC token with npm shell: bash run: | @@ -59,3 +113,28 @@ jobs: fi echo 'npm OIDC token exchange succeeded.' + + - name: Dry-run an unpublished package version with pnpm + shell: bash + run: | + set -euo pipefail + PROBE_DIRECTORY="$RUNNER_TEMP/npm-oidc-probe" + mkdir "$PROBE_DIRECTORY" + node --input-type=module -e ' + import { writeFileSync } from "node:fs"; + const [path, name, runId, attempt] = process.argv.slice(1); + writeFileSync(path, JSON.stringify({ + name, + version: "0.0.0-oidc-probe." + runId + "." + attempt, + })); + ' "$PROBE_DIRECTORY/package.json" "$PACKAGE_NAME" "$GITHUB_RUN_ID" "$GITHUB_RUN_ATTEMPT" + + pnpm_command=(pnpm) + if [ '${{ matrix.bypass_safe_chain }}' = 'true' ]; then + pnpm_command=("$PNPM_HOME/pnpm") + fi + "${pnpm_command[@]}" --dir "$PROBE_DIRECTORY" publish --access public --no-git-checks --dry-run 2>&1 | tee "$RUNNER_TEMP/pnpm-oidc.log" + if [[ "$(< "$RUNNER_TEMP/pnpm-oidc.log")" == *'Skipped OIDC: ERR_PNPM_AUTH_TOKEN_FETCH'* ]]; then + echo '::error::pnpm failed to exchange the OIDC token.' + exit 1 + fi