From c3e11127abd3f4b7f01c40db22d403e116a1987f Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Sat, 2 May 2026 10:48:15 +0200 Subject: [PATCH] fix: append (not prepend) action node dir to PATH for npm bootstrap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #239 prepended `dirname(process.execPath)` to PATH so npm's `#!/usr/bin/env node` shebang resolves on GHE self-hosted runners where node isn't on PATH. But on runners with a prior `setup-node` step, this shadowed the user's installed toolchain with the runner-bundled node (e.g. externals/node24/bin), pairing the user's npm with a mismatched node — or picking up a broken `npm` shipped next to the runner-bundled node. Append instead so a user-installed toolchain on PATH keeps precedence; the runner's node dir remains as a fallback for the original #234 case where node isn't on PATH at all. Fixes #240 --- dist/index.js | Bin 1433466 -> 1433466 bytes src/install-pnpm/run.ts | 14 +++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/dist/index.js b/dist/index.js index 453a9a6f09b5ac97716343dd352ae273467606ff..f19d850f725f590db76538d0020e5d4d8f02d0de 100644 GIT binary patch delta 82 zcmeyhFZ|cO@P-z~7N!>F7M2#)7Pc1l7LFFq7OocV7M>Q~7QPn#7J(MQ7NHj57LhHY lji)7Yv=j66Qc}|rOLIzqbWUb&W=U$1w&V7hr$rwM0|3wW9pnH2 delta 82 zcmeyhFZ|cO@P-z~7N!>F7M2#)7Pc1l7LFFq7OocV7M>Q~7QPn#7J(MQ7NHj57LhHY lji)6XwG;F7Qc}|rOLIzqbWUb&W=U$1cFy*hr$rwM0|3k#9pnH2 diff --git a/src/install-pnpm/run.ts b/src/install-pnpm/run.ts index e22ee79..e20fa60 100644 --- a/src/install-pnpm/run.ts +++ b/src/install-pnpm/run.ts @@ -29,16 +29,20 @@ export async function runSelfInstaller(inputs: Inputs): Promise { await writeFile(path.join(dest, 'package.json'), packageJson) await writeFile(path.join(dest, 'package-lock.json'), JSON.stringify(lockfile)) - // Prepend the action's node directory to PATH so npm's + // Append 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`. + // self-hosted) where node isn't already on PATH. Append (not + // prepend) so a user-installed toolchain on PATH — e.g. from a + // prior `setup-node` step — keeps precedence; otherwise the + // runner-bundled node would shadow it and pair the user's npm + // with a mismatched node version. 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 npmEnv = { ...process.env, [pathKey]: currentPath ? currentPath + path.delimiter + nodeDir : nodeDir } const npmExitCode = await runCommand('npm', ['ci'], { cwd: dest, env: npmEnv }) if (npmExitCode !== 0) { return npmExitCode