diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd845a6d7..e4d16879a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,17 @@ env: # don't fully support it, causing SIGABRT in Node.js processes. # See: https://github.com/actions/runner-images/issues/13602 UV_USE_IO_URING: "0" + # CI Node.js versions, pinned to exact patches and used as the single source + # of truth for every actions/setup-node step (referenced as + # ${{ env.NODE_VERSION_xx }}). Node 24.17.0 / 22.23.0 (CVE-2026-48931's + # http.Agent fix) added a `data` listener on idle agent sockets that makes + # keep-alive fetch reuse throw false ERR_STREAM_PREMATURE_CLOSE + # ("Premature close" — hit by the skill-eval planner talking to external + # APIs). Fixed in 24.18.0 / 22.23.1 (nodejs/node#64004). A floating major + # ("24"/"22") silently reuses the runner's pre-cached buggy patch, so pin the + # exact patched versions here and bump them in one place. + NODE_VERSION_22: "22.23.1" + NODE_VERSION_24: "24.18.0" jobs: changes: @@ -128,7 +139,7 @@ jobs: - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v6 with: - node-version: "22" + node-version: ${{ env.NODE_VERSION_22 }} - uses: actions/cache@v5 id: cache with: @@ -183,7 +194,7 @@ jobs: - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v6 with: - node-version: "22" + node-version: ${{ env.NODE_VERSION_22 }} - uses: actions/cache@v5 id: cache with: @@ -214,7 +225,7 @@ jobs: - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v6 with: - node-version: "24" + node-version: ${{ env.NODE_VERSION_24 }} - uses: actions/cache@v5 id: cache with: @@ -249,7 +260,7 @@ jobs: - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v6 with: - node-version: "22" + node-version: ${{ env.NODE_VERSION_22 }} - uses: actions/cache@v5 id: cache with: @@ -710,13 +721,10 @@ jobs: - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v6 with: - # Pin exact patch: Node 24.17.0 (and 22.23.0) shipped CVE-2026-48931's - # http.Agent fix, which added a `data` listener on idle sockets that - # makes keep-alive fetch reuse throw false ERR_STREAM_PREMATURE_CLOSE. - # This surfaces as "Premature close" in the skill-eval planner's HTTP - # calls. Fixed in 24.18.0 (nodejs/node#64004). A floating "24" silently - # reuses the runner's pre-cached buggy 24.17.0, so pin the exact patch. - node-version: "24.18.0" + # Pinned to a patched 24 — the skill-eval planner makes keep-alive + # HTTPS calls and would hit the ERR_STREAM_PREMATURE_CLOSE regression + # on a floating "24". See NODE_VERSION_24 in the top-level env block. + node-version: ${{ env.NODE_VERSION_24 }} - uses: actions/cache@v5 id: cache with: @@ -755,7 +763,10 @@ jobs: - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v6 with: - node-version: ${{ matrix.node }} + # Matrix entries stay bare majors ("22"/"24") for the job name and the + # `matrix.node == '22'` artifact guard below; map each to its exact + # patched version from the central env block here. + node-version: ${{ matrix.node == '24' && env.NODE_VERSION_24 || env.NODE_VERSION_22 }} - uses: actions/cache@v5 id: cache with: @@ -818,7 +829,7 @@ jobs: # build doesn't rely on whatever ships on the runner image. - uses: actions/setup-node@v6 with: - node-version: "24" + node-version: ${{ env.NODE_VERSION_24 }} - uses: actions/cache@v5 id: cache with: diff --git a/.github/workflows/docs-preview.yml b/.github/workflows/docs-preview.yml index 2c056af98..ac5fb00ba 100644 --- a/.github/workflows/docs-preview.yml +++ b/.github/workflows/docs-preview.yml @@ -27,6 +27,13 @@ concurrency: group: docs-preview-${{ github.ref }} cancel-in-progress: true +env: + # Pin Node to an exact patched version (single source of truth). A floating + # "24" can reuse the runner's pre-cached 24.17.0, which carries the + # ERR_STREAM_PREMATURE_CLOSE regression on keep-alive fetch reuse + # (nodejs/node#64004, fixed in 24.18.0). + NODE_VERSION_24: "24.18.0" + jobs: preview: runs-on: ubuntu-latest @@ -35,11 +42,12 @@ jobs: - uses: pnpm/action-setup@v4 - # Astro 6 requires Node >= 22.12. Pin an explicit version so the docs - # build doesn't rely on whatever ships on the runner image. + # Astro 6 requires Node >= 22.12. Pin an exact patched version (see + # NODE_VERSION_24) so the docs build doesn't rely on the runner image's + # default. - uses: actions/setup-node@v6 with: - node-version: "24" + node-version: ${{ env.NODE_VERSION_24 }} - uses: actions/cache@v5 id: cache diff --git a/.github/workflows/eval-skill-fork.yml b/.github/workflows/eval-skill-fork.yml index 649d5f0b0..7edffa694 100644 --- a/.github/workflows/eval-skill-fork.yml +++ b/.github/workflows/eval-skill-fork.yml @@ -9,6 +9,15 @@ permissions: statuses: write pull-requests: write +env: + # Pin Node to the exact patched release rather than floating on the runner's + # pre-cached major. Node 24.17.0 (CVE-2026-48931's http.Agent fix) added a + # `data` listener on idle agent sockets that makes keep-alive fetch reuse + # throw a false ERR_STREAM_PREMATURE_CLOSE — exactly the failure the + # skill-eval planner hits talking to external APIs. Fixed in 24.18.0 + # (nodejs/node#64004). Keep in sync with NODE_VERSION_24 in ci.yml. + NODE_VERSION_24: "24.18.0" + jobs: remove-labels-on-sync: name: Reset eval labels @@ -38,6 +47,10 @@ jobs: - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v6 + with: + node-version: ${{ env.NODE_VERSION_24 }} + - uses: actions/cache@v5 id: cache with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3e2930c70..3e712f083 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,6 +15,13 @@ permissions: contents: write pull-requests: write +env: + # Pin Node to an exact patched version (single source of truth). A floating + # "22" can reuse the runner's pre-cached 22.23.0, which carries the + # ERR_STREAM_PREMATURE_CLOSE regression on keep-alive fetch reuse + # (nodejs/node#64004, fixed in 22.23.1). + NODE_VERSION_22: "22.23.1" + jobs: release: runs-on: ubuntu-latest @@ -33,7 +40,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 22 + node-version: ${{ env.NODE_VERSION_22 }} - name: Prepare release uses: getsentry/craft@v2 env: diff --git a/.github/workflows/sentry-release.yml b/.github/workflows/sentry-release.yml index 6a9fc42ce..e2c335fce 100644 --- a/.github/workflows/sentry-release.yml +++ b/.github/workflows/sentry-release.yml @@ -13,6 +13,14 @@ permissions: contents: read issues: write +env: + # Pin Node to an exact patched version (single source of truth). A floating + # "22" can reuse the runner's pre-cached 22.23.0, which carries the + # ERR_STREAM_PREMATURE_CLOSE regression on keep-alive fetch reuse + # (nodejs/node#64004, fixed in 22.23.1). This job installs from and uploads + # over HTTPS. + NODE_VERSION_22: "22.23.1" + jobs: finalize: name: Finalize Sentry Release @@ -34,12 +42,13 @@ jobs: with: fetch-depth: 0 - # The sentry npm package requires Node.js >= 22.12 — pin an explicit - # version so this job doesn't depend on the runner image's default. + # The sentry npm package requires Node.js >= 22.12 — pin an exact patched + # version (see NODE_VERSION_22) so this job doesn't depend on the runner + # image's default. - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: 22 + node-version: ${{ env.NODE_VERSION_22 }} - name: Install CLI run: npm install -g "sentry@${VERSION}"