From 768051fcbaffe93e6ab11b9aff208652780465e3 Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Thu, 6 Aug 2026 23:08:13 +0000 Subject: [PATCH] ci: move every action off the deprecated Node 20 runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub is forcing Node 20 actions onto Node 24 and annotating every run that uses one. The publish workflow named three, but the same actions are pinned across ci, test and threatcrush-scan, and two more there — upload-artifact@v4 and github-script@v7 — are on node20 as well, along with codeql-action@v3. actions/checkout v4 -> v7 actions/setup-node v4 -> v7 pnpm/action-setup v4 -> v6 actions/upload-artifact v4 -> v7 actions/github-script v7 -> v9 codeql-action/upload-sarif v3 -> v4 Every target confirmed `runs.using: node24` before bumping, rather than assumed from the version number — codeql-action v3 is node20 and v4 is not, which the deprecation notice does not mention. Two breaking changes were checked against actual usage rather than skipped: setup-node v5 added automatic caching driven by the `packageManager` field and v6 narrowed it to npm. Every caller here passes `cache: pnpm` explicitly, so the automatic path is never consulted, and pnpm/action-setup already runs first in all three workflows — which explicit pnpm caching requires. github-script v9 makes `require('@actions/github')` fail, since that package is now ESM-only. The one script here requires `fs` and uses the injected `github` client, neither of which is affected; v9's own README still documents `require` for builtins and local modules. Not fixed here: profullstack/coinpaybot@v0 is also node20 and has no newer tag, so coinpay.yml keeps warning until that action is rebuilt in its own repo. Co-Authored-By: Claude Opus 5 --- .github/workflows/ci.yml | 6 +++--- .github/workflows/publish.yml | 12 +++++++++--- .github/workflows/test.yml | 6 +++--- .github/workflows/threatcrush-scan.yml | 10 +++++----- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1848b63..4aea4b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,14 +21,14 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 # pnpm version is read from the "packageManager" field in package.json. # Do not pin a version here — it conflicts with packageManager and fails # with ERR_PNPM_BAD_PM_VERSION. - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@v6 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v7 with: node-version: '22' cache: pnpm diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 88681f6..cc9dd8a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,6 +26,12 @@ # Removing it changed the error from E404 to ENEEDAUTH but did not publish. # actions/setup-node#1551, npm/cli#9088. # +# Since then setup-node v7 stopped exporting a dummy NODE_AUTH_TOKEN when no +# token is set (actions/setup-node#1558), which is the half of that trap that +# corrupted .npmrc under OIDC. It does not affect the token path — we set +# NODE_AUTH_TOKEN explicitly — but it means trusted publishing is worth a third +# attempt before the 2FA-bypass deprecation below forces one. +# # Worth knowing when this is next revisited: npm is restricting tokens that # bypass 2FA for direct publishing, so the token path has a horizon. # https://gh.io/npm-gat-bypass2fa-deprecation @@ -48,17 +54,17 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 # pnpm version is read from the "packageManager" field in package.json. # Do not pin a version here — it conflicts with packageManager and fails # with ERR_PNPM_BAD_PM_VERSION. - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@v6 # `registry-url` is what makes setup-node write the .npmrc line that feeds # NODE_AUTH_TOKEN to npm. Required for token auth — and the thing to delete # first if this ever moves back to OIDC. - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v7 with: node-version: 24 cache: pnpm diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4b357ad..0d24c45 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,14 +17,14 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 # pnpm version is read from the "packageManager" field in package.json. # Do not pin a version here — it conflicts with packageManager and fails # with ERR_PNPM_BAD_PM_VERSION. - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@v6 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v7 with: node-version: 22 cache: pnpm diff --git a/.github/workflows/threatcrush-scan.yml b/.github/workflows/threatcrush-scan.yml index d9190b6..83fed51 100644 --- a/.github/workflows/threatcrush-scan.yml +++ b/.github/workflows/threatcrush-scan.yml @@ -19,9 +19,9 @@ jobs: timeout-minutes: 15 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v7 with: node-version: "20" @@ -151,7 +151,7 @@ jobs: - name: Upload to the Security tab if: always() && 'true' == 'true' continue-on-error: true - uses: github/codeql-action/upload-sarif@v3 + uses: github/codeql-action/upload-sarif@v4 with: sarif_file: threatcrush.sarif category: threatcrush @@ -236,7 +236,7 @@ jobs: - name: Upload SARIF artifact if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: threatcrush-sarif path: threatcrush.sarif @@ -251,7 +251,7 @@ jobs: - name: Comment on PR if: always() && github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' continue-on-error: true - uses: actions/github-script@v7 + uses: actions/github-script@v9 with: script: | const fs = require('fs');