|
1 | 1 | import * as child_process from "node:child_process"; |
2 | 2 | import * as fs from "node:fs/promises"; |
3 | 3 | import * as path from "node:path"; |
4 | | -import { execPath } from "node:process"; |
5 | 4 | import { bsc_exe, rescript_legacy_exe } from "#cli/bins"; |
6 | 5 |
|
7 | | -// On GitHub Actions runners, `npm` is not a native binary but a shell script |
8 | | -// installed alongside the `node` executable in the hostedtoolcache directory. |
9 | | -// Spawning it directly by name (`spawn("npm")`) can fail with ENOENT because |
10 | | -// the PATH in CI sometimes gets polluted with bogus entries (e.g. `/tmp/xfs-*` |
11 | | -// prepended), causing `execvp` to stop searching before reaching the real npm. |
12 | | -// To avoid relying on PATH resolution, we resolve `npm` relative to |
13 | | -// `process.execPath` (the current Node binary) and run it with `shell: true` |
14 | | -// so the shebang (`#!/usr/bin/env node`) inside the npm script is honoured. |
15 | | -const npmBin = path.join(path.dirname(execPath), "npm"); |
16 | | - |
17 | 6 | /** |
18 | 7 | * @typedef {{ |
19 | 8 | * throwOnFail?: boolean, |
@@ -61,32 +50,22 @@ export function setup(cwd = process.cwd()) { |
61 | 50 | async function exec(command, args = [], options = {}) { |
62 | 51 | const { throwOnFail = options.stdio === "inherit" } = options; |
63 | 52 |
|
64 | | - if (process.env.CI) { |
65 | | - console.log("[exec] PATH =", options.env?.PATH ?? process.env.PATH); |
66 | | - console.log("[npm] using", npmBin); |
67 | | - } |
68 | | - |
69 | | - const stdoutChunks = []; |
70 | | - const stderrChunks = []; |
71 | | - |
72 | | - // build env and clean PATH |
| 53 | + // Build env |
73 | 54 | const env = options.env |
74 | 55 | ? { ...process.env, ...options.env } |
75 | 56 | : { ...process.env }; |
76 | | - if (env.PATH) { |
77 | | - const parts = env.PATH.split(":").filter(Boolean); |
78 | | - const valid = []; |
79 | | - for (const p of parts) { |
80 | | - try { |
81 | | - const stat = await fs.stat(p); |
82 | | - if (stat.isDirectory()) valid.push(p); |
83 | | - } catch { |
84 | | - // ignore non‑existent dirs |
85 | | - } |
86 | | - } |
87 | | - env.PATH = valid.join(":"); |
| 57 | + |
| 58 | + // Clean PATH only in CI: drop bogus /tmp/xfs-* entries |
| 59 | + if (process.env.CI && env.PATH) { |
| 60 | + env.PATH = env.PATH.split(":") |
| 61 | + .filter(p => !p.startsWith("/tmp/xfs-") && p !== "") |
| 62 | + .join(":"); |
| 63 | + console.log("[exec] cleaned PATH =", env.PATH); |
88 | 64 | } |
89 | 65 |
|
| 66 | + const stdoutChunks = []; |
| 67 | + const stderrChunks = []; |
| 68 | + |
90 | 69 | const subprocess = child_process.spawn(command, args, { |
91 | 70 | cwd, |
92 | 71 | shell: process.platform === "win32", |
|
0 commit comments