mirror of
https://github.com/pnpm/pnpm.git
synced 2026-05-18 22:02:53 -04:00
fix(exe): restore execute bit on node-gyp shims in @pnpm/exe (#11485)
- 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`.
This commit is contained in:
6
.changeset/exe-node-gyp-executable.md
Normal file
6
.changeset/exe-node-gyp-executable.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/exe": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
Restore the execute bit on the `node-gyp` shims packed inside `@pnpm/exe` (`dist/node-gyp-bin/node-gyp`, `dist/node-gyp-bin/node-gyp.cmd`, and `dist/node_modules/node-gyp/bin/node-gyp.js`). Without this, `pnpm/action-setup`'s standalone path (used on runners with Node.js < 22.13) failed any install whose lifecycle script invoked `node-gyp rebuild` with `sh: 1: node-gyp: Permission denied` [#11483](https://github.com/pnpm/pnpm/issues/11483).
|
||||
@@ -22,6 +22,16 @@ const EXPERIMENTAL_PKGS = new Set([
|
||||
'pnpm-agent',
|
||||
])
|
||||
|
||||
// Files that must be packed with mode 0755 in both `pnpm` and `@pnpm/exe`.
|
||||
// `@pnpm/exe` ships the same `dist/` tree as `pnpm`, so the two manifests'
|
||||
// `publishConfig.executableFiles` lists must stay identical — otherwise the
|
||||
// shims end up packed at 0644 in one of the tarballs (see #11483).
|
||||
const PUBLISH_EXECUTABLE_FILES = [
|
||||
'./dist/node-gyp-bin/node-gyp',
|
||||
'./dist/node-gyp-bin/node-gyp.cmd',
|
||||
'./dist/node_modules/node-gyp/bin/node-gyp.js',
|
||||
]
|
||||
|
||||
// Packages whose tests spawn the local pnpm CLI binary (pnpm/bin/pnpm.mjs)
|
||||
// and therefore need the CLI bundle (pnpm/dist/pnpm.mjs) to be built first.
|
||||
const PKGS_NEEDING_CLI_COMPILE = new Set([
|
||||
@@ -137,6 +147,8 @@ export default async (workspaceDir: string) => { // eslint-disable-line
|
||||
]) {
|
||||
manifest.optionalDependencies![depName] = 'workspace:*'
|
||||
}
|
||||
manifest.publishConfig ??= {}
|
||||
manifest.publishConfig.executableFiles = [...PUBLISH_EXECUTABLE_FILES]
|
||||
}
|
||||
return sortKeysInManifest(manifest)
|
||||
}
|
||||
@@ -337,6 +349,7 @@ async function updateManifest (workspaceDir: string, manifest: ProjectManifest,
|
||||
delete scripts._compile
|
||||
if (manifest.name === CLI_PKG_NAME) {
|
||||
manifest.publishConfig!.tag = nextTag
|
||||
manifest.publishConfig!.executableFiles = [...PUBLISH_EXECUTABLE_FILES]
|
||||
}
|
||||
if (scripts['.test']) {
|
||||
if (scripts.pretest) {
|
||||
|
||||
@@ -78,6 +78,11 @@
|
||||
"pn": "pn",
|
||||
"pnpx": "pnpx",
|
||||
"pnx": "pnx"
|
||||
}
|
||||
},
|
||||
"executableFiles": [
|
||||
"./dist/node-gyp-bin/node-gyp",
|
||||
"./dist/node-gyp-bin/node-gyp.cmd",
|
||||
"./dist/node_modules/node-gyp/bin/node-gyp.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user