fix(bun-install): forward process.env so child bun install inherits proxy settings (fixes #3528)
Root cause: runBunInstallWithDetails() invoked spawnWithWindowsHide() without passing env, so the child bun install lost https_proxy / http_proxy / NO_PROXY and other parent env vars. @npmcli/agent then received an empty proxy URL and rejected fetch with 'fetch() proxy.url must be a non-empty string', breaking plugin auto-install on networks that require an outbound proxy. Fix: pass env: process.env to spawnWithWindowsHide so the child bun install inherits the full parent environment, including proxy variables. Verification: added a regression test that sets https_proxy/http_proxy on process.env and asserts those values are forwarded to the spawn options. Test fails before the fix and passes after. typecheck clean. Other pre-existing path-separator test failures on Windows are unrelated to this change.
This commit is contained in:
@@ -70,12 +70,40 @@ describe("runBunInstallWithDetails", () => {
|
|||||||
expect(getOpenCodeCacheDirSpy).toHaveBeenCalledTimes(1)
|
expect(getOpenCodeCacheDirSpy).toHaveBeenCalledTimes(1)
|
||||||
expect(spawnWithWindowsHideSpy).toHaveBeenCalledWith(["bun", "install"], {
|
expect(spawnWithWindowsHideSpy).toHaveBeenCalledWith(["bun", "install"], {
|
||||||
cwd: "/tmp/opencode-cache/packages",
|
cwd: "/tmp/opencode-cache/packages",
|
||||||
|
env: process.env,
|
||||||
stdout: "pipe",
|
stdout: "pipe",
|
||||||
stderr: "pipe",
|
stderr: "pipe",
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("#when bun install runs with proxy environment variables set", () => {
|
||||||
|
it("#then forwards process.env so child bun install inherits proxy settings (issue #3528)", async () => {
|
||||||
|
// given
|
||||||
|
const originalHttpsProxy = process.env.https_proxy
|
||||||
|
const originalHttpProxy = process.env.http_proxy
|
||||||
|
process.env.https_proxy = "http://proxy.example.com:3128"
|
||||||
|
process.env.http_proxy = "http://proxy.example.com:3128"
|
||||||
|
|
||||||
|
try {
|
||||||
|
// when
|
||||||
|
await runBunInstallWithDetails()
|
||||||
|
|
||||||
|
// then
|
||||||
|
const callArgs = spawnWithWindowsHideSpy.mock.calls[0]
|
||||||
|
const spawnOptions = callArgs?.[1] as { env?: Record<string, string | undefined> } | undefined
|
||||||
|
expect(spawnOptions?.env).toBeDefined()
|
||||||
|
expect(spawnOptions?.env?.https_proxy).toBe("http://proxy.example.com:3128")
|
||||||
|
expect(spawnOptions?.env?.http_proxy).toBe("http://proxy.example.com:3128")
|
||||||
|
} finally {
|
||||||
|
if (originalHttpsProxy === undefined) delete process.env.https_proxy
|
||||||
|
else process.env.https_proxy = originalHttpsProxy
|
||||||
|
if (originalHttpProxy === undefined) delete process.env.http_proxy
|
||||||
|
else process.env.http_proxy = originalHttpProxy
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("#when bun install uses piped output", () => {
|
describe("#when bun install uses piped output", () => {
|
||||||
it("#then passes pipe mode to the spawned process", async () => {
|
it("#then passes pipe mode to the spawned process", async () => {
|
||||||
// given
|
// given
|
||||||
@@ -87,6 +115,7 @@ describe("runBunInstallWithDetails", () => {
|
|||||||
expect(result).toEqual({ success: true })
|
expect(result).toEqual({ success: true })
|
||||||
expect(spawnWithWindowsHideSpy).toHaveBeenCalledWith(["bun", "install"], {
|
expect(spawnWithWindowsHideSpy).toHaveBeenCalledWith(["bun", "install"], {
|
||||||
cwd: "/tmp/opencode-cache/packages",
|
cwd: "/tmp/opencode-cache/packages",
|
||||||
|
env: process.env,
|
||||||
stdout: "pipe",
|
stdout: "pipe",
|
||||||
stderr: "pipe",
|
stderr: "pipe",
|
||||||
})
|
})
|
||||||
@@ -104,6 +133,7 @@ describe("runBunInstallWithDetails", () => {
|
|||||||
expect(result).toEqual({ success: true })
|
expect(result).toEqual({ success: true })
|
||||||
expect(spawnWithWindowsHideSpy).toHaveBeenCalledWith(["bun", "install"], {
|
expect(spawnWithWindowsHideSpy).toHaveBeenCalledWith(["bun", "install"], {
|
||||||
cwd: "/tmp/opencode-cache/packages",
|
cwd: "/tmp/opencode-cache/packages",
|
||||||
|
env: process.env,
|
||||||
stdout: "inherit",
|
stdout: "inherit",
|
||||||
stderr: "inherit",
|
stderr: "inherit",
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ export async function runBunInstallWithDetails(options?: RunBunInstallOptions):
|
|||||||
try {
|
try {
|
||||||
const proc = spawnWithWindowsHide(["bun", "install"], {
|
const proc = spawnWithWindowsHide(["bun", "install"], {
|
||||||
cwd: cacheDir,
|
cwd: cacheDir,
|
||||||
|
env: process.env,
|
||||||
stdout: outputMode,
|
stdout: outputMode,
|
||||||
stderr: outputMode,
|
stderr: outputMode,
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user