diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b935a90..1c00395 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,24 +26,83 @@ jobs: needs: should-run uses: ./.github/workflows/build.yml - # Release only after all prerequisites complete - release: + # Generate release benchmark documentation on consistent Namespace hardware. + # GitHub-hosted CPU performance is too variable for published comparisons. + benchmark-docs: runs-on: namespace-profile-default needs: [lint, test, build] + permissions: + contents: read steps: - name: Checkout repository uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - name: Setup Node.js uses: actions/setup-node@v4 with: + # Preserve the runtime used by the release benchmarks before OIDC + # publishing required the release job itself to use Node.js 24. node-version: 25 cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Update benchmark documentation + run: npm run update-benchmark-docs -- --quiet + + - name: Upload benchmark documentation + # Pass only non-executable benchmark output into the privileged job. + uses: actions/upload-artifact@v4 + with: + name: release-benchmark-docs-${{ github.sha }} + path: README.md + if-no-files-found: error + retention-days: 1 + + # Release only after all prerequisites complete + release: + # npm trusted publishing currently accepts only GitHub-hosted runners. + runs-on: ubuntu-latest + needs: benchmark-docs + permissions: + contents: write + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Download benchmark documentation + # Extract outside the checkout so the artifact cannot add package files. + uses: actions/download-artifact@v4 + with: + name: release-benchmark-docs-${{ github.sha }} + path: ${{ runner.temp }}/release-benchmark-docs + + - name: Apply benchmark documentation + run: cp "$RUNNER_TEMP/release-benchmark-docs/README.md" README.md + + - name: Verify benchmark documentation scope + # The trusted job consumes the Namespace result only as README data; + # executable release inputs must still come from the checked-out SHA. + run: git diff --exit-code -- . ':(exclude)README.md' + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: 24 registry-url: 'https://registry.npmjs.org' + package-manager-cache: false + + - name: Install npm with trusted publishing support + # Trusted publishing requires npm >=11.5.1; pin the major so a future + # npm release cannot silently change the privileged release toolchain. + run: npm install --global npm@11 - name: Install dependencies run: npm ci @@ -57,8 +116,9 @@ jobs: git config --global user.email "github-actions[bot]@users.noreply.github.com" - name: Release - run: npm run release -- --ci + # Skip release-it's token-only npm preflight and override only its + # benchmark hook: Namespace already generated the README, so the + # variable GitHub-hosted CPU must not replace those measurements. + run: npm run release -- --ci --npm.skipChecks --hooks.after:bump="npm run format" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}