From 13e6a1c6a75bc8297bbe827e5251a56fd7de2783 Mon Sep 17 00:00:00 2001 From: Keesan Date: Thu, 13 Aug 2026 01:19:22 -0400 Subject: [PATCH] fix(release): accept npm pack JSON envelopes --- scripts/root-release-guard.mjs | 11 ++++++++--- scripts/tests/root-release-guard.test.mjs | 11 +++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/scripts/root-release-guard.mjs b/scripts/root-release-guard.mjs index 2e03d6f..edce23c 100644 --- a/scripts/root-release-guard.mjs +++ b/scripts/root-release-guard.mjs @@ -113,9 +113,7 @@ export async function inspectPackedFiles(options = {}) { { cwd: rootDir }, ); const packArtifacts = extractPackJsonPayload(packRun.stdout); - const files = Array.isArray(packArtifacts) - ? packArtifacts[0]?.files?.map((entry) => entry.path).filter((entry) => typeof entry === "string") - : []; + const files = extractPackFilePaths(packArtifacts); if (files.length === 0) { throw new Error("npm pack --dry-run did not report any packaged files."); @@ -131,6 +129,13 @@ export function extractPackJsonPayload(stdout) { return JSON.parse(jsonPayload); } +export function extractPackFilePaths(packArtifacts) { + const artifact = Array.isArray(packArtifacts) ? packArtifacts[0] : packArtifacts; + return Array.isArray(artifact?.files) + ? artifact.files.map((entry) => entry.path).filter((entry) => typeof entry === "string") + : []; +} + export async function assertVendoredCliManifest(rootDir) { const manifestPath = path.join(rootDir, "dist", "vendor", "cli", "package.json"); const rootManifest = JSON.parse(await readFile(path.join(rootDir, "package.json"), "utf8")); diff --git a/scripts/tests/root-release-guard.test.mjs b/scripts/tests/root-release-guard.test.mjs index 23623ce..dc07b27 100644 --- a/scripts/tests/root-release-guard.test.mjs +++ b/scripts/tests/root-release-guard.test.mjs @@ -9,6 +9,7 @@ import { assertPackedSurface, assertRootVersionPolicy, assertVendoredCliManifest, + extractPackFilePaths, runRootReleaseGuard, } from "../root-release-guard.mjs"; @@ -85,6 +86,16 @@ test("assertPackedSurface rejects forbidden vendored implementation paths", () = ); }); +test("extractPackFilePaths accepts npm pack object and array envelopes", () => { + const artifact = { + filename: "martin-loop-0.5.0.tgz", + files: [{ path: "package.json" }, { path: "dist/index.js" }], + }; + + assert.deepEqual(extractPackFilePaths([artifact]), ["package.json", "dist/index.js"]); + assert.deepEqual(extractPackFilePaths(artifact), ["package.json", "dist/index.js"]); +}); + test("assertVendoredCliManifest accepts the sanitized vendored CLI package manifest", async () => { await withTempRoot(async (tempRoot) => { await writeFile(