Compare commits

...

2 Commits

Author SHA1 Message Date
Ben Quarmby 26f6d4f2c5 fix: use npm co-located with the action node binary (#239)
* fix: use npm co-located with the action node binary

* fix: resolve npm by absolute path; guard against unset PATH

Follow-up to 5a9e198. Two refinements to the GHE self-hosted runner fix:

- Spawn npm via `path.join(dirname(process.execPath), 'npm[.cmd]')`
  instead of relying on PATH lookup. This matches the original PR
  description and is robust against PATH-shadowed npm installations.
- Avoid `"<dir>:undefined"` leaking into PATH when `process.env.PATH`
  is unset (rare, but possible in stripped environments).

PATH still has the node directory prepended so npm's
`#!/usr/bin/env node` shebang can resolve node on Linux/macOS.

* fix: revert npm to PATH lookup; runner externals lacks npm

Revert 42e75a1's switch to absolute-path npm resolution. The premise
that npm is co-located with the action's node binary is false on
GitHub-hosted runners: `process.execPath` points into
`runner/externals/node24/bin/`, which contains node only — not npm.
The absolute-path spawn produced ENOENT on Linux/macOS and
"not recognized" on Windows.

Go back to spawning `'npm'` and relying on PATH lookup, which works
on standard runners (npm is on PATH from the runner image) and on
the GHE self-hosted setup that motivated the original fix. Keep the
node-directory prepend so npm's `#!/usr/bin/env node` shebang
resolves, and keep the unset-PATH guard.

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2026-04-30 22:28:41 +02:00
Zoltan Kochan 903f9c1a6e fix: update pnpm to 11.0.0-rc.5 2026-04-21 20:27:39 +02:00
4 changed files with 240 additions and 184 deletions
+150 -149
View File
File diff suppressed because one or more lines are too long
+73 -29
View File
@@ -5,17 +5,18 @@
"packages": {
"": {
"dependencies": {
"@pnpm/exe": "11.0.0-rc.2"
"@pnpm/exe": "11.0.0-rc.5"
}
},
"node_modules/@pnpm/exe": {
"version": "11.0.0-rc.2",
"resolved": "https://registry.npmjs.org/@pnpm/exe/-/exe-11.0.0-rc.2.tgz",
"integrity": "sha512-EkL8nZApA0wUA7c5hDdbeuyNUkmkDRBn8evxx4O79SMlEX1D6XspEu9EkLmT+sqrHsAwKzHTHsNYwTSOuKavRg==",
"version": "11.0.0-rc.5",
"resolved": "https://registry.npmjs.org/@pnpm/exe/-/exe-11.0.0-rc.5.tgz",
"integrity": "sha512-HT1HxzeFc6RVIMhngQZ7bQgTNzF0IckeFpOvnwCJKfsjfsD/po3LvUVsidCvpALxCWOft1TuBZUkdHq03pEolA==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"@reflink/reflink": "0.1.19"
"@reflink/reflink": "0.1.19",
"detect-libc": "^2.0.3"
},
"bin": {
"pn": "pn",
@@ -27,18 +28,20 @@
"url": "https://opencollective.com/pnpm"
},
"optionalDependencies": {
"@pnpm/linux-arm64": "11.0.0-rc.2",
"@pnpm/linux-x64": "11.0.0-rc.2",
"@pnpm/macos-arm64": "11.0.0-rc.2",
"@pnpm/macos-x64": "11.0.0-rc.2",
"@pnpm/win-arm64": "11.0.0-rc.2",
"@pnpm/win-x64": "11.0.0-rc.2"
"@pnpm/linux-arm64": "11.0.0-rc.5",
"@pnpm/linux-x64": "11.0.0-rc.5",
"@pnpm/linuxstatic-arm64": "11.0.0-rc.5",
"@pnpm/linuxstatic-x64": "11.0.0-rc.5",
"@pnpm/macos-arm64": "11.0.0-rc.5",
"@pnpm/macos-x64": "11.0.0-rc.5",
"@pnpm/win-arm64": "11.0.0-rc.5",
"@pnpm/win-x64": "11.0.0-rc.5"
}
},
"node_modules/@pnpm/linux-arm64": {
"version": "11.0.0-rc.2",
"resolved": "https://registry.npmjs.org/@pnpm/linux-arm64/-/linux-arm64-11.0.0-rc.2.tgz",
"integrity": "sha512-aw7wUq6ffXAfP7r9ZKa7GQmCoh/2EJcdb5ghkc8cgz0O2RZCmIaHqMV2O049iSAtblANkOu5uhwAZW7DKMJa3A==",
"version": "11.0.0-rc.5",
"resolved": "https://registry.npmjs.org/@pnpm/linux-arm64/-/linux-arm64-11.0.0-rc.5.tgz",
"integrity": "sha512-AreNJJI0r5oEsv5+i+FMVK8AeYs0MpWTGWc2GQwf7qi/w8uA8UxVlIDwhgwY+R6YgdrYVrEjgbU4WcqIqYfgog==",
"cpu": [
"arm64"
],
@@ -52,9 +55,41 @@
}
},
"node_modules/@pnpm/linux-x64": {
"version": "11.0.0-rc.2",
"resolved": "https://registry.npmjs.org/@pnpm/linux-x64/-/linux-x64-11.0.0-rc.2.tgz",
"integrity": "sha512-aCItGORv4lUjYldScyhd7uxgXQI3s1B1s99u5Eb42KRRC4Q8DAf7dboXbLGk7rQLjx8F9xIiaD7QX7YR8+MWEQ==",
"version": "11.0.0-rc.5",
"resolved": "https://registry.npmjs.org/@pnpm/linux-x64/-/linux-x64-11.0.0-rc.5.tgz",
"integrity": "sha512-NzZPWeIVxCEfQs84wR/O3IND2HSDOClPB2L8vvkWb8KQ4pczOG2x3aNkltXDwYVKxvw4URmwct5u57JGTEvtfg==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/pnpm"
}
},
"node_modules/@pnpm/linuxstatic-arm64": {
"version": "11.0.0-rc.5",
"resolved": "https://registry.npmjs.org/@pnpm/linuxstatic-arm64/-/linuxstatic-arm64-11.0.0-rc.5.tgz",
"integrity": "sha512-xK+U/fJDkvzs4ktswrCZ03cTSEAeFTfgUG88r2J+6JEDGuY/foNOMnnSNOiSplpaufY+Ie+uL+PEDlTyIy46Xg==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/pnpm"
}
},
"node_modules/@pnpm/linuxstatic-x64": {
"version": "11.0.0-rc.5",
"resolved": "https://registry.npmjs.org/@pnpm/linuxstatic-x64/-/linuxstatic-x64-11.0.0-rc.5.tgz",
"integrity": "sha512-Z1kSilngaM2URfPhBjam/xhMDAn5jl8V0L5CjG/Gg5unmKkipyF93OYMpfnny7A9p1KWi6sNql/KufzUmRP4Eg==",
"cpu": [
"x64"
],
@@ -68,9 +103,9 @@
}
},
"node_modules/@pnpm/macos-arm64": {
"version": "11.0.0-rc.2",
"resolved": "https://registry.npmjs.org/@pnpm/macos-arm64/-/macos-arm64-11.0.0-rc.2.tgz",
"integrity": "sha512-WsLK8St9Hpwp26qqdFVdLdDlJ3CLJVIkcFwP7G9b+HtkPZOx+Z9AGZ8iam1B7HSrf8XomZWlq0vntHDsc2uPTg==",
"version": "11.0.0-rc.5",
"resolved": "https://registry.npmjs.org/@pnpm/macos-arm64/-/macos-arm64-11.0.0-rc.5.tgz",
"integrity": "sha512-98p3ilSzkyusC2bxk7Ya34CWt9MeJy/+kpXfwn9YgnOD7GDqCjYY9dlPB9yrkdtKUUMeOIvOuacAQTWnCg2GOQ==",
"cpu": [
"arm64"
],
@@ -84,9 +119,9 @@
}
},
"node_modules/@pnpm/macos-x64": {
"version": "11.0.0-rc.2",
"resolved": "https://registry.npmjs.org/@pnpm/macos-x64/-/macos-x64-11.0.0-rc.2.tgz",
"integrity": "sha512-hiC0khjWqSu6l25rs52izVhPM+6IVbp89pLRyBMYTe5x2a9iydUsCloPl7E+SuNiZ5cNnG28qj3PDzc5upeH/Q==",
"version": "11.0.0-rc.5",
"resolved": "https://registry.npmjs.org/@pnpm/macos-x64/-/macos-x64-11.0.0-rc.5.tgz",
"integrity": "sha512-WZ9UqjTbZN+dMZcy4qaPDsEo4sxTIrw5H+fDvdxT1GUavsf8SBDpvzZMHrGDQ/k22H8oKvPtJ+RGd/Ie5dvbuA==",
"cpu": [
"x64"
],
@@ -100,9 +135,9 @@
}
},
"node_modules/@pnpm/win-arm64": {
"version": "11.0.0-rc.2",
"resolved": "https://registry.npmjs.org/@pnpm/win-arm64/-/win-arm64-11.0.0-rc.2.tgz",
"integrity": "sha512-+bo8RmPQyPCKq+h1GE/QHJ7Ybt/4bWZLUSgXJQS6UOB7ar56g2g4ii1X5+8htkkdXxS5Uoj2TVqRjKp6hkkAdA==",
"version": "11.0.0-rc.5",
"resolved": "https://registry.npmjs.org/@pnpm/win-arm64/-/win-arm64-11.0.0-rc.5.tgz",
"integrity": "sha512-hxgDmF4xpSVvUPvH+HdMllvHcV2zuYUn/uK182gzFvZ9DE0xEGVj09XaSn5VMbpa32i25oIqaT89QfMcOw/TJg==",
"cpu": [
"arm64"
],
@@ -116,9 +151,9 @@
}
},
"node_modules/@pnpm/win-x64": {
"version": "11.0.0-rc.2",
"resolved": "https://registry.npmjs.org/@pnpm/win-x64/-/win-x64-11.0.0-rc.2.tgz",
"integrity": "sha512-srkbMALQgb4taTzKMlwqBZV+JHTh15jN4/FOVOGQ5XadjXdpJOievkvp/m87WankP8MX8th+mJhD9RX/rDOSOw==",
"version": "11.0.0-rc.5",
"resolved": "https://registry.npmjs.org/@pnpm/win-x64/-/win-x64-11.0.0-rc.5.tgz",
"integrity": "sha512-B1H/6jhzW/6VLr8Bc3zOhMd2P3srANWytuBq0uppR5c7OJwUlqXqJtB6Q4nOEjWYZ2sA5m2xuFiaMeioZiiqgA==",
"cpu": [
"x64"
],
@@ -277,6 +312,15 @@
"engines": {
"node": ">= 10"
}
},
"node_modules/detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
"license": "Apache-2.0",
"engines": {
"node": ">=8"
}
}
}
}
+4 -4
View File
@@ -5,13 +5,13 @@
"packages": {
"": {
"dependencies": {
"pnpm": "11.0.0-rc.2"
"pnpm": "11.0.0-rc.5"
}
},
"node_modules/pnpm": {
"version": "11.0.0-rc.2",
"resolved": "https://registry.npmjs.org/pnpm/-/pnpm-11.0.0-rc.2.tgz",
"integrity": "sha512-JkEMwm1mi63d4ToKzyx1ytALgqR3vMHi/mKd1B1reP4/stm7Ujr/951qkfBr6bkKYDJUPzC19zkxI5yCCqXwAQ==",
"version": "11.0.0-rc.5",
"resolved": "https://registry.npmjs.org/pnpm/-/pnpm-11.0.0-rc.5.tgz",
"integrity": "sha512-xGn7aqE6meV67JNc17hv9CJwH0YC7KwiMdPcIJEFhuv7a1CntFXQd47CKuVpEtjY6I6fngoDwIdaakF4OpShvQ==",
"license": "MIT",
"bin": {
"pn": "bin/pnpm.mjs",
+13 -2
View File
@@ -29,7 +29,17 @@ export async function runSelfInstaller(inputs: Inputs): Promise<number> {
await writeFile(path.join(dest, 'package.json'), packageJson)
await writeFile(path.join(dest, 'package-lock.json'), JSON.stringify(lockfile))
const npmExitCode = await runCommand('npm', ['ci'], { cwd: dest })
// Prepend the action's node directory to PATH so npm's
// `#!/usr/bin/env node` shebang resolves on runners (e.g. GHE
// self-hosted) where node isn't already on PATH. npm itself is
// resolved via PATH — on the GitHub Actions runner it is not
// co-located with `process.execPath`.
const nodeDir = path.dirname(process.execPath)
// On Windows, the PATH key casing varies; search case-insensitively.
const pathKey = Object.keys(process.env).find(k => k.toUpperCase() === 'PATH') ?? 'PATH'
const currentPath = process.env[pathKey]
const npmEnv = { ...process.env, [pathKey]: currentPath ? nodeDir + path.delimiter + currentPath : nodeDir }
const npmExitCode = await runCommand('npm', ['ci'], { cwd: dest, env: npmEnv })
if (npmExitCode !== 0) {
return npmExitCode
}
@@ -155,10 +165,11 @@ function getSystemNodeVersion(): Promise<{ major: number; minor: number }> {
})
}
function runCommand(cmd: string, args: string[], opts: { cwd: string }): Promise<number> {
function runCommand(cmd: string, args: string[], opts: { cwd: string; env?: Record<string, string | undefined> }): Promise<number> {
return new Promise<number>((resolve, reject) => {
const cp = spawn(cmd, args, {
cwd: opts.cwd,
env: opts.env,
stdio: ['pipe', 'inherit', 'inherit'],
shell: process.platform === 'win32',
})