diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 73174b20e..b5aa64610 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,8 +45,8 @@ env: # node-sqlite3-wasm driver. The npm-package job runs a Node 20 matrix entry # so that fallback path is exercised in CI rather than only in production. NODE_VERSION_20: "20.20.2" - NODE_VERSION_22: "22.23.1" - NODE_VERSION_24: "24.18.0" + NODE_VERSION_22: "22.23.4" + NODE_VERSION_24: "24.22.1" jobs: changes: diff --git a/.github/workflows/eval-skill-fork.yml b/.github/workflows/eval-skill-fork.yml index a98602387..8de3f3efc 100644 --- a/.github/workflows/eval-skill-fork.yml +++ b/.github/workflows/eval-skill-fork.yml @@ -16,7 +16,7 @@ env: # 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" + NODE_VERSION_24: "24.22.1" jobs: remove-labels-on-sync: diff --git a/.github/workflows/pr-risk-labels-test.yml b/.github/workflows/pr-risk-labels-test.yml index eae41c54b..ab2791b6e 100644 --- a/.github/workflows/pr-risk-labels-test.yml +++ b/.github/workflows/pr-risk-labels-test.yml @@ -24,5 +24,5 @@ jobs: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: - node-version: '24.18.0' + node-version: '24.22.1' - run: node --test .github/tests/pr-risk-labels.test.mjs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3e712f083..05ce9d272 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ env: # "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" + NODE_VERSION_22: "22.23.4" jobs: release: diff --git a/.github/workflows/sentry-release.yml b/.github/workflows/sentry-release.yml index e2c335fce..3915f8357 100644 --- a/.github/workflows/sentry-release.yml +++ b/.github/workflows/sentry-release.yml @@ -19,7 +19,7 @@ env: # 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" + NODE_VERSION_22: "22.23.4" jobs: finalize: diff --git a/packages/cli/test/lib/delta-upgrade.mocked.test.ts b/packages/cli/test/lib/delta-upgrade.mocked.test.ts index f6186ab59..5cc53f135 100644 --- a/packages/cli/test/lib/delta-upgrade.mocked.test.ts +++ b/packages/cli/test/lib/delta-upgrade.mocked.test.ts @@ -15,6 +15,7 @@ import { copyFileSync, existsSync, unlinkSync, writeFileSync } from "node:fs"; import { readFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; +import { zstdCompressSync } from "node:zlib"; import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { useTestConfigDir } from "../helpers.js"; @@ -134,13 +135,19 @@ describe("resolveStableDelta", () => { }, ]; - // A fake patch that is valid TRDIFF10 header but will fail during application - // (header says 0 control/diff/new size, which produces an empty file) - const emptyTrdiff10 = new Uint8Array(32); - // Set magic: "TRDIFF10" - const magic = new TextEncoder().encode("TRDIFF10"); - emptyTrdiff10.set(magic, 0); - // All sizes stay 0 — this will produce an empty output + // A valid TRDIFF10 patch that produces an empty file, so the final + // SHA-256 check fails. Each block is a real zstd frame because newer Node + // releases reject zero-length zstd input with "unexpected end of file". + const emptyBlock = zstdCompressSync(Buffer.alloc(0)); + const emptyTrdiff10 = new Uint8Array(32 + emptyBlock.length * 3); + const header = new DataView(emptyTrdiff10.buffer); + emptyTrdiff10.set(new TextEncoder().encode("TRDIFF10"), 0); + header.setBigInt64(8, BigInt(emptyBlock.length), true); // controlLen + header.setBigInt64(16, BigInt(emptyBlock.length), true); // diffLen + // newSize at offset 24 stays 0 + emptyTrdiff10.set(emptyBlock, 32); + emptyTrdiff10.set(emptyBlock, 32 + emptyBlock.length); + emptyTrdiff10.set(emptyBlock, 32 + emptyBlock.length * 2); mockFetch(async (url) => { const urlStr = String(url);