Skip to content

fix(scripts): make publish:check run on Windows - #382

Merged
stackbilt-admin merged 4 commits into
mainfrom
fix/publish-check-windows
Oct 18, 2026
Merged

stackbilt-admin merged 4 commits into
mainfrom
fix/publish-check-windows

Conversation

@stackbilt-admin

@stackbilt-admin stackbilt-admin commented Oct 18, 2026 •

Copy link
Copy Markdown
Member

Closes #367

pnpm run publish:check crashed on Windows before checking anything. This makes scripts/assert-packages-publishable.mjs portable:

  • pnpm spawn: under pnpm run, npm_execpath points at pnpm's JS entry, so the script runs it with process.execPath (no shell on any platform). Run directly (node scripts/...), it falls back to pnpm on PATH, through the shell on win32 (pnpm.cmd) with a pre-quoted command line (avoids Node's DEP0190 warning for args+shell). Linux/macOS without npm_execpath use plain pnpm as before.
  • Spawn failures: result.error and termination signals are reported; stdout/stderr are no longer dereferenced when undefined.
  • Tarball reading: no more system tar. Tarballs are gunzipped with node:zlib and read with a small ustar reader (handles prefix, pax path= and GNU L long names; skips directories). No new dependencies.

No CHANGELOG entry: maintainer-only tooling, nothing ships to users.

Verification (Windows 11, Git Bash, Node 24, pnpm 9.15.9)

  • pnpm run publish:check: passes for all 13 packages.
  • node scripts/assert-packages-publishable.mjs with npm_execpath unset (shell fallback): passes, no deprecation warning.
  • Negative: a planted packages/cli/dist/__tests__/fake.test.js is reported (@stackbilt/cli: packed test/build-only artifacts: package/dist/__tests__/fake.test.js), exit 1.
  • The reader's entry count for the cli tarball matches tar --force-local -tf (203 = 203).
  • Full test suite serially: only the 3 known Windows-only failures (bootstrap bootstrap: phases 6/7 collect warnings without printing them; absoluteAiDirArg misses Windows paths on POSIX #307, context-refresh, serve-context).

The release workflow (ubuntu) runs pnpm run publish:check; on Linux the code path is either the npm_execpath path or the unchanged plain pnpm spawn.

Review follow-up (second commit)

  • npm_execpath is used only when its file name is pnpm.cjs/pnpm.js/pnpm.mjs; npm's npm-cli.js under a pnpm-managed Node (.../pnpm/nodejs/...) previously matched and would have run npm pack.
  • On the win32 shell fallback, an argument containing % is refused with a clear error (cmd.exe expands %VAR% inside double quotes, which sent tarballs to a different directory that cleanup missed).
  • Every tar entry name (symlinks, hardlinks, directories) is checked against the forbidden patterns, as tar -tf did; GNU K headers are skipped.
  • A tarball without an end-of-archive marker throws; the prefix field is used only with POSIX ustar\0 + 00 magic.
  • Re-verified: pnpm run publish:check and the shell fallback pass; crafted archives (pax/GNU long names, ustar prefix, symlink/hardlink test files, truncated header/body/gzip, base-256 size) are listed or fail closed.

Not addressed (nits): no header checksum validation; the pax parser takes the first path= match rather than walking records; no automated tests for the reader.

🤖 Generated with Claude Code

kovermier and others added 4 commits October 17, 2026 19:58
- Spawn pnpm via npm_execpath (node + pnpm's JS entry) when run under
  `pnpm run`; otherwise fall back to `pnpm` on PATH, through the shell
  on win32 where it is pnpm.cmd.
- Report result.error / signal when a spawn fails instead of
  dereferencing an undefined stdout.
- Read the packed tarballs in-process (zlib + a minimal ustar reader)
  instead of shelling out to tar, whose GNU flavour under Git Bash
  treats C:/... paths as remote hosts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Use npm_execpath only when its file name is pnpm.(c|m)js, so npm under
  a pnpm-managed Node is not mistaken for pnpm.
- Refuse a %-containing argument on the win32 cmd.exe path instead of
  letting cmd expand it into a different pack directory.
- Check every tar entry name (links, directories) against the forbidden
  patterns, as tar -tf did; skip GNU K headers.
- Fail on a missing end-of-archive marker; require POSIX ustar magic
  before using the prefix field.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
release.yml runs it before publishing; running it on every PR exercises the script's Linux path so a change to it can't first fail at release time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@stackbilt-admin
stackbilt-admin merged commit fdd1cf0 into main Oct 18, 2026
8 checks passed
@stackbilt-admin
stackbilt-admin deleted the fix/publish-check-windows branch October 18, 2026 01:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

publish:check crashes on Windows (spawns pnpm without a shell; tar reads C: as a host)

2 participants