mirror of
https://github.com/pnpm/action-setup.git
synced 2026-05-28 15:39:50 +08:00
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>
This commit is contained in:
parent
903f9c1a6e
commit
26f6d4f2c5
66
dist/index.js
vendored
66
dist/index.js
vendored
File diff suppressed because one or more lines are too long
@ -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',
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user