From 7f6f6f3cc6ec3b38e7b375cf344c06d6bbbf7127 Mon Sep 17 00:00:00 2001 From: Arul Sharma <31745423+arul28@users.noreply.github.com> Date: Wed, 2 Sep 2026 12:47:49 -0400 Subject: [PATCH 1/2] fix(sdk): match Windows runtime archive name on npm publish The first runtime publish looked for ade-win32-x64.exe.native.tar.gz. Releases publish ade-win32-x64.native.tar.gz, so checksum verification stopped at 9 of 10 files. Co-authored-by: Cursor --- .../workflows/publish-runtime-packages.yml | 48 +++++++++++-------- .../scripts/build-runtime-npm-packages.mjs | 10 +++- .../build-runtime-npm-packages.test.mjs | 20 ++++++++ 3 files changed, 57 insertions(+), 21 deletions(-) diff --git a/.github/workflows/publish-runtime-packages.yml b/.github/workflows/publish-runtime-packages.yml index bd8288e93..319fd8fea 100644 --- a/.github/workflows/publish-runtime-packages.yml +++ b/.github/workflows/publish-runtime-packages.yml @@ -129,30 +129,40 @@ jobs: if: steps.token.outputs.present == 'true' run: | set -euo pipefail - cd release-artifacts - if [ ! -s SHA256SUMS ]; then + if [ ! -s release-artifacts/SHA256SUMS ]; then echo "::error::The release published no SHA256SUMS; refusing to repackage unverified bytes." exit 1 fi # Only the ten runtime assets are checked: the release also carries # desktop artifacts this workflow never downloads, and `-c` fails on a - # manifest line whose file is absent. - # `|| true` on every grep. Under `set -euo pipefail` a grep that - # matches nothing exits 1 and aborts the step with no message, which - # is the most likely failure here (a renamed release asset) and the - # one the count diagnostic below exists to explain. - : > expected.sums - for TARGET in darwin-arm64 darwin-x64 linux-x64 linux-arm64; do - grep -E " ade-${TARGET}(\.native\.tar\.gz)?$" SHA256SUMS >> expected.sums || true - done - grep -E " ade-win32-x64\.exe(\.native\.tar\.gz)?$" SHA256SUMS >> expected.sums || true - if [ "$(wc -l < expected.sums)" -ne 10 ]; then - echo "::error::Expected 10 runtime entries in SHA256SUMS, found $(wc -l < expected.sums)." - cat expected.sums - exit 1 - fi - sha256sum -c expected.sums - rm expected.sums + # manifest line whose file is absent. Names come from runtimeAssetNames + # so Windows stays `ade-win32-x64.native.tar.gz`, matching SHA256SUMS + # and release-core.yml, not `ade-win32-x64.exe.native.tar.gz`. + node --input-type=module <<'EOF' + import fs from "node:fs"; + import { RUNTIME_TARGETS, runtimeAssetNames } from "./apps/ade-cli/scripts/build-runtime-npm-packages.mjs"; + + const sums = fs.readFileSync("release-artifacts/SHA256SUMS", "utf8").split(/\r?\n/); + const expected = []; + for (const { target } of RUNTIME_TARGETS) { + const { binaryAsset, archiveAsset } = runtimeAssetNames(target); + for (const name of [binaryAsset, archiveAsset]) { + const line = sums.find((row) => row.endsWith(` ${name}`)); + if (!line) { + console.error(`::error::SHA256SUMS has no entry for ${name}.`); + process.exit(1); + } + expected.push(line); + } + } + if (expected.length !== 10) { + console.error(`::error::Expected 10 runtime entries in SHA256SUMS, found ${expected.length}.`); + process.exit(1); + } + fs.writeFileSync("release-artifacts/expected.sums", `${expected.join("\n")}\n`); + EOF + (cd release-artifacts && sha256sum -c expected.sums) + rm release-artifacts/expected.sums - name: Build the platform packages if: steps.token.outputs.present == 'true' diff --git a/apps/ade-cli/scripts/build-runtime-npm-packages.mjs b/apps/ade-cli/scripts/build-runtime-npm-packages.mjs index eac79bece..22206d9f9 100644 --- a/apps/ade-cli/scripts/build-runtime-npm-packages.mjs +++ b/apps/ade-cli/scripts/build-runtime-npm-packages.mjs @@ -61,8 +61,14 @@ export function runtimePackageName(target) { /** The two release assets that make one platform package. */ export function runtimeAssetNames(target) { - const binaryAsset = target === "win32-x64" ? `ade-${target}.exe` : `ade-${target}`; - return { binaryAsset, archiveAsset: `${binaryAsset}.native.tar.gz` }; + // The Windows launcher is `ade-win32-x64.exe`. The native archive next to it + // is `ade-win32-x64.native.tar.gz` — not `ade-win32-x64.exe.native.tar.gz`. + // `release-core.yml` and SHA256SUMS spell it that way; gluing `.native.tar.gz` + // onto the binary name looks for a file the release never publishes. + if (target === "win32-x64") { + return { binaryAsset: "ade-win32-x64.exe", archiveAsset: "ade-win32-x64.native.tar.gz" }; + } + return { binaryAsset: `ade-${target}`, archiveAsset: `ade-${target}.native.tar.gz` }; } /** diff --git a/apps/ade-cli/scripts/build-runtime-npm-packages.test.mjs b/apps/ade-cli/scripts/build-runtime-npm-packages.test.mjs index 7c9a81afc..8928980c3 100644 --- a/apps/ade-cli/scripts/build-runtime-npm-packages.test.mjs +++ b/apps/ade-cli/scripts/build-runtime-npm-packages.test.mjs @@ -121,6 +121,26 @@ test("sets the executable bit on the runtime binary", () => { }); }); +test("Windows native archive is ade-win32-x64.native.tar.gz, not glued onto .exe", () => { + assert.deepEqual(runtimeAssetNames("win32-x64"), { + binaryAsset: "ade-win32-x64.exe", + archiveAsset: "ade-win32-x64.native.tar.gz", + }); + assert.deepEqual(runtimeAssetNames("linux-x64"), { + binaryAsset: "ade-linux-x64", + archiveAsset: "ade-linux-x64.native.tar.gz", + }); +}); + +test("publish workflow checksum step uses runtimeAssetNames", () => { + const workflow = fs.readFileSync( + new URL("../../../.github/workflows/publish-runtime-packages.yml", import.meta.url), + "utf8", + ); + assert.match(workflow, /runtimeAssetNames/); + assert.doesNotMatch(workflow, /ade-win32-x64\\.exe\(\\\.native\\.tar\\.gz\)\?/); +}); + test("names the Windows binary ade.exe", () => { withTempDirs(({ artifacts, out }) => { writeFakeArtifacts(artifacts, "win32-x64"); From 98df7d5fc7f2ec46b92c8056f1183fbfa2552b98 Mon Sep 17 00:00:00 2001 From: Arul Sharma <31745423+arul28@users.noreply.github.com> Date: Wed, 2 Sep 2026 12:51:53 -0400 Subject: [PATCH 2/2] fix(sdk): raise npm pack buffer for runtime native trees A real v1.2.72 native listing overflows Node's 1 MiB execFileSync default, so the publish job died with ENOBUFS after checksums already passed. Co-authored-by: Cursor --- apps/ade-cli/scripts/build-runtime-npm-packages.mjs | 4 ++++ apps/ade-cli/scripts/build-runtime-npm-packages.test.mjs | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/apps/ade-cli/scripts/build-runtime-npm-packages.mjs b/apps/ade-cli/scripts/build-runtime-npm-packages.mjs index 22206d9f9..eebe54486 100644 --- a/apps/ade-cli/scripts/build-runtime-npm-packages.mjs +++ b/apps/ade-cli/scripts/build-runtime-npm-packages.mjs @@ -332,6 +332,9 @@ function listFilesRelative(dir, base = dir) { return out; } +/** 50 MiB: a real native tree's `npm pack --dry-run --json` listing exceeds Node's 1 MiB default. */ +export const NPM_PACK_MAX_BUFFER_BYTES = 50 * 1024 * 1024; + /** * `npm pack --dry-run`, spawned the one way that works on every platform. * @@ -353,6 +356,7 @@ function defaultPackRunner(cwd) { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], + maxBuffer: NPM_PACK_MAX_BUFFER_BYTES, windowsHide: true, windowsVerbatimArguments: invocation.windowsVerbatimArguments, }); diff --git a/apps/ade-cli/scripts/build-runtime-npm-packages.test.mjs b/apps/ade-cli/scripts/build-runtime-npm-packages.test.mjs index 8928980c3..808a98051 100644 --- a/apps/ade-cli/scripts/build-runtime-npm-packages.test.mjs +++ b/apps/ade-cli/scripts/build-runtime-npm-packages.test.mjs @@ -8,6 +8,7 @@ import test from "node:test"; import { EXCEPTION_FILE_NAME, META_PACKAGE_NAME, + NPM_PACK_MAX_BUFFER_BYTES, RUNTIME_TARGETS, buildMetaPackage, buildRuntimePackage, @@ -121,6 +122,12 @@ test("sets the executable bit on the runtime binary", () => { }); }); +test("npm pack dry-run buffer is large enough for a real native tree", () => { + assert.ok(NPM_PACK_MAX_BUFFER_BYTES >= 50 * 1024 * 1024); + const source = fs.readFileSync(new URL("./build-runtime-npm-packages.mjs", import.meta.url), "utf8"); + assert.match(source, /maxBuffer:\s*NPM_PACK_MAX_BUFFER_BYTES/); +}); + test("Windows native archive is ade-win32-x64.native.tar.gz, not glued onto .exe", () => { assert.deepEqual(runtimeAssetNames("win32-x64"), { binaryAsset: "ade-win32-x64.exe",