From 5cdd395f7ea8a6f1e23101c573788d7b8f066b3b Mon Sep 17 00:00:00 2001 From: Gergo Magyar Date: Tue, 9 Jun 2026 13:50:19 +0000 Subject: [PATCH] fix(publish): make the coverage guard's npm-pack inspection script-safe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The prepack guard shelled out to `npm pack --dry-run --ignore-scripts --json`, but the `--ignore-scripts` flag is not reliably honored by npm pack's prepare/prepack lifecycle on the CI npm — so build.js ran, polluted the --json stdout with `[build] …`, and the guard's JSON.parse threw. That broke every `npm pack` (packaged-install-smoke on ubuntu+windows) and failed the guard's own real-repo unit test (the only coverage-job failure). Force script-skipping via the reliable `npm_config_ignore_scripts` env config (also removes the prepack re-entry/recursion risk) and parse defensively from the JSON-array start. --- gitnexus/scripts/assert-publish-grammar-coverage.cjs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/gitnexus/scripts/assert-publish-grammar-coverage.cjs b/gitnexus/scripts/assert-publish-grammar-coverage.cjs index 4ca9806e2..d27259f5e 100644 --- a/gitnexus/scripts/assert-publish-grammar-coverage.cjs +++ b/gitnexus/scripts/assert-publish-grammar-coverage.cjs @@ -93,8 +93,18 @@ function packFileSet(cwd) { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], + // The `--ignore-scripts` FLAG is not reliably honored by `npm pack`'s + // prepare/prepack lifecycle on every npm version — when it isn't, build.js + // runs (polluting this --json stdout with `[build] …`) AND, since this guard + // runs in prepack, the inner pack would re-enter the guard (recursion). The + // `npm_config_ignore_scripts` env config IS reliable, so set it too. + env: { ...process.env, npm_config_ignore_scripts: 'true' }, }); - const parsed = JSON.parse(out); + // Defensive: if any lifecycle/build output still precedes the JSON array on + // stdout (e.g. `[build] …`), parse from the array start (`[` then `{`) rather + // than the raw stream. `[build]` does NOT match (no `{` after the bracket). + const start = out.search(/\[\s*\{/); + const parsed = JSON.parse(start >= 0 ? out.slice(start) : out); const files = (parsed[0] && parsed[0].files) || []; return new Set(files.map((f) => f.path.replace(/\\/g, '/'))); }