Skip to content

fix(exe): restore execute bit on node-gyp shims in @pnpm/exe#11485

Merged
zkochan merged 2 commits into
mainfrom
fix/11483
May 6, 2026
Merged

fix(exe): restore execute bit on node-gyp shims in @pnpm/exe#11485
zkochan merged 2 commits into
mainfrom
fix/11483

Conversation

@zkochan

@zkochan zkochan commented May 6, 2026

Copy link
Copy Markdown
Member

Summary

  • Closes @pnpm/exe 11.x ships node-gyp shims without execute bit, breaking native rebuilds #11483.
  • @pnpm/exe@11.x was packing dist/node-gyp-bin/node-gyp, dist/node-gyp-bin/node-gyp.cmd, and dist/node_modules/node-gyp/bin/node-gyp.js with mode 0644 instead of 0755. Any install whose lifecycle script invokes node-gyp rebuild while pnpm has prepended dist/node-gyp-bin/ to PATH failed with sh: 1: node-gyp: Permission denied — most visibly via pnpm/action-setup@v6's standalone path on GitHub Actions runners with system Node < 22.13.
  • The regular pnpm package's package.json already declares publishConfig.executableFiles for these three shims, which pnpm publish honors by packing matching tar entries with mode 0755 (see releasing/commands/src/publish/pack.ts:273 and the bins-driven mode selection at pack.ts:360-361). @pnpm/exe's package.json was missing the same field, so the shims it copies from pnpm/dist/ shipped with 0644. This PR mirrors the field into @pnpm/exe.
  • To prevent the two manifests from drifting again, meta-updater is now the single source of truth for the executable-files list and writes it into both pnpm/package.json and pnpm/artifacts/exe/package.json.

Test plan

  • pn lint:meta passes (meta-updater output matches both committed manifests).
  • Verify the published @pnpm/exe tarball has mode 0755 on the three node-gyp shims:
    pn --filter @pnpm/exe pack --pack-destination /tmp/pnpm-exe-pack
    tar -tvzf /tmp/pnpm-exe-pack/pnpm-exe-*.tgz | grep -E 'node-gyp(-bin/node-gyp(\.cmd)?|/bin/node-gyp\.js)$'
    Each of the three matched entries should show -rwxr-xr-x.
  • Sanity-check that publishing @pnpm/exe still produces a valid tarball (existing publish CI).

Written by an agent (Claude Code, claude-opus-4-7).

Summary by CodeRabbit

  • Bug Fixes

    • Restored execute permissions on bundled node-gyp binaries to prevent "permission denied" errors when running node-gyp rebuild on older Node.js versions.
  • Chores

    • Updated packaging/publish metadata and tooling to ensure node-gyp runtime files are marked and published with executable permissions.

Copilot AI review requested due to automatic review settings May 6, 2026 08:29
@coderabbitai

coderabbitai Bot commented May 6, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c106f9b7-fde5-4c9d-9bd3-66ff24250771

📥 Commits

Reviewing files that changed from the base of the PR and between 04e69e6 and 94f16ff.

📒 Files selected for processing (1)
  • .meta-updater/src/index.ts

📝 Walkthrough

Walkthrough

Adds packaging metadata and manifest-updater logic to ensure three node-gyp shim files are published with executable permissions; includes changeset documenting the fix.

Changes

Node-gyp Executable Permissions Fix

Layer / File(s) Summary
Changeset Documentation
.changeset/exe-node-gyp-executable.md
Adds a patch changeset entry describing restoration of execute bits on node-gyp shims and lists affected files and context.
Package Metadata
pnpm/artifacts/exe/package.json
Adds publishConfig.executableFiles with ./dist/node-gyp-bin/node-gyp, ./dist/node-gyp-bin/node-gyp.cmd, and ./dist/node_modules/node-gyp/bin/node-gyp.js.
Manifest Updater Logic
meta-updater/src/index.ts
Introduces PUBLISH_EXECUTABLE_FILES constant and sets manifest.publishConfig.executableFiles (initializing publishConfig when needed) in package.json update flows and CLI package manifest update.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰
I dug a hole for bits gone meek,
Restored the perms the users seek,
Now shims can hop and native build,
No more “Permission denied” chilled,
Hooray — the rabbit fixed the tweak!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main fix: restoring execute bit on node-gyp shims in @pnpm/exe, which directly addresses the core issue.
Linked Issues check ✅ Passed The PR addresses the primary objectives from issue #11483: restoring execute permissions (mode 0755) on three node-gyp shims and ensuring @pnpm/exe packaging preserves executable modes by mirroring publishConfig.executableFiles.
Out of Scope Changes check ✅ Passed All changes are scoped to the fix: a changeset entry, updates to @pnpm/exe's package.json with executableFiles metadata, and meta-updater logic to sync the field between pnpm and @pnpm/exe. No unrelated changes detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/11483

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a packaging regression in the @pnpm/exe artifact where the bundled node-gyp shim scripts were published without the executable bit, which can break native module rebuilds (e.g. lifecycle scripts invoking node-gyp rebuild) when @pnpm/exe is used.

Changes:

  • Add publishConfig.executableFiles to pnpm/artifacts/exe/package.json so the three node-gyp shim files are packed with mode 0755.
  • Add a Changeset to publish the fix as a patch release.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
pnpm/artifacts/exe/package.json Declares publishConfig.executableFiles for the node-gyp shims so packaging assigns executable permissions.
.changeset/exe-node-gyp-executable.md Adds a patch Changeset entry describing the permission fix and linking to #11483.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…and @pnpm/exe

Define the node-gyp shim list once in meta-updater so the two manifests
can't drift out of sync the next time someone adds, removes, or renames an
executable file under dist/.
@zkochan zkochan merged commit 29c2e7a into main May 6, 2026
13 checks passed
@zkochan zkochan deleted the fix/11483 branch May 6, 2026 08:46
zkochan added a commit that referenced this pull request May 6, 2026
- Closes #11483.
- `@pnpm/exe@11.x` was packing `dist/node-gyp-bin/node-gyp`, `dist/node-gyp-bin/node-gyp.cmd`, and `dist/node_modules/node-gyp/bin/node-gyp.js` with mode `0644` instead of `0755`. Any install whose lifecycle script invokes `node-gyp rebuild` while pnpm has prepended `dist/node-gyp-bin/` to `PATH` failed with `sh: 1: node-gyp: Permission denied` — most visibly via `pnpm/action-setup@v6`'s standalone path on GitHub Actions runners with system Node < 22.13.
- The regular `pnpm` package's `package.json` already declares `publishConfig.executableFiles` for these three shims, which `pnpm publish` honors by packing matching tar entries with mode `0755` (see `releasing/commands/src/publish/pack.ts:273` and the `bins`-driven mode selection at `pack.ts:360-361`). `@pnpm/exe`'s `package.json` was missing the same field, so the shims it copies from `pnpm/dist/` shipped with `0644`. This PR mirrors the field into `@pnpm/exe`.
- To prevent the two manifests from drifting again, meta-updater is now the single source of truth for the executable-files list and writes it into both `pnpm/package.json` and `pnpm/artifacts/exe/package.json`.
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.

@pnpm/exe 11.x ships node-gyp shims without execute bit, breaking native rebuilds

2 participants