test: Git for Windows Bash launcher shadows curl and sleep fixture stubs

Aperta
#2,905 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@ax3cubed ci sta già lavorando.

Dal 13/10/2026.

Valutazione

Difficoltà
3/5
Tempo stimato
Mezza giornata
Idoneità per principianti
72/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
bash, node.js, typescript
Ambito
ci-cd, testing

Direzione di ricerca

The failing fixtures are in tests/mock-launcher.test.ts and tests/release-publish-workflow.test.ts. Start by reading how each one builds its PATH for spawnSync, then compare with the quoted-positional-argument approach in tests/test-script.test.ts. Run the two files under Git Bash with the bin\bash.exe setup from the report. Done when the fixture curl and sleep stubs resolve on that setup, the existing assertions still pass, and no timeouts or Windows skips are changed.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Bug description

  • This concerns the Node SDK repository's contributor tests, not an underlying OpenAI API issue.

The PowerShell setup documented in CONTRIBUTING.md adds Git for Windows' bin directory to PATH. With C:\Program Files\Git\bin\bash.exe, the healthy mock-daemon fixture and the missing-release-CI fixture do not consistently select their own command stubs. The Bash launcher places Git's system directories ahead of the fixture PATH supplied to spawnSync.

Consequently, the mock fixture invokes the real Git curl instead of its synthetic health-check stub, and the release fixture invokes /usr/bin/sleep instead of its no-op Node sleep stub. This causes false contributor-test failures without an SDK or production-workflow defect.

Version and environment

  • Main commit: 2b12eabd29733c8de495bb183b41632e091b4994; package version 7.32.0.
  • OS: Windows 10 x64, build 19045.
  • Node.js v24.19.0; pnpm 11.5.1; Vitest 5.0.1.
  • Git for Windows 2.49.0.windows.1.
  • Dependencies installed with pnpm install --frozen-lockfile.
  • No real API credentials, OpenAI requests, or GitHub API requests are involved in these fixtures.

To reproduce

From PowerShell in a clean checkout, following the documented Windows shell setup:

$env:PATH = 'C:\Program Files\Git\bin;' + $env:PATH
pnpm exec vitest run --config vitest.config.mts tests/mock-launcher.test.ts tests/release-publish-workflow.test.ts --reporter=verbose

Observed failures:

Steady mock launcher > runs the pinned local launcher without pnpm in daemon mode
EPERM during cleanupFixture / rmSync

release commit CI gate > handles missing CI for the immutable release commit
spawnSync bash ETIMEDOUT

The mock failure reproduced in the grouped run and two independent single-case runs. The release failure reproduced in grouped and single-case runs; its synchronous cleanup can additionally report EPERM and mask the timeout.

Control, changing only which existing Bash entrypoint is selected, without editing source, assertions, or timeouts:

$env:PATH = 'C:\Program Files\Git\usr\bin;' + $env:PATH
pnpm exec vitest run --config vitest.config.mts tests/mock-launcher.test.ts tests/release-publish-workflow.test.ts --reporter=verbose

Result: 20 passed, 2 Linux-only tests skipped. All four launcher cases pass; the missing-CI case completes in approximately 5.3 seconds with its expected failure diagnostic.

Expected: fixture curl and sleep are selected regardless of which documented Git Bash entrypoint starts the test process.

Actual: bin\bash.exe startup shadows those fixtures with /mingw64/bin/curl and /usr/bin/sleep.

Small command-selection reproduction

Run this credential-free Node snippet on the affected Windows setup. It creates and removes only its own temporary directory, and does not invoke curl, sleep, or any API:

const { spawnSync } = require('node:child_process');
const { mkdtempSync, writeFileSync, rmSync } = require('node:fs');
const { tmpdir } = require('node:os');
const path = require('node:path');

const fixture = mkdtempSync(path.join(tmpdir(), 'openai-bash-path-probe-'));
const bash = 'C:\\Program Files\\Git\\bin\\bash.exe';
const bashFixture = fixture
  .replace(/^[A-Za-z]:[\\/]/, prefix => `/${prefix[0].toLowerCase()}/`)
  .replace(/\\/g, '/');
try {
  for (const command of ['curl', 'sleep']) {
    writeFileSync(path.join(fixture, command), '#!/usr/bin/env node\nprocess.exit(0);\n', { mode: 0o755 });
  }
  const env = { ...process.env, PATH: `${fixture}${path.delimiter}${process.env.PATH}` };
  const before = spawnSync(bash, ['-c', 'command -v curl; command -v sleep'], { env, encoding: 'utf8' });
  const after = spawnSync(bash, [
    '-c', 'PATH="$1:$PATH"; command -v curl; command -v sleep', 'bash', bashFixture,
  ], { env, encoding: 'utf8' });
  console.log('env PATH only:\n' + before.stdout);
  console.log('PATH after Bash startup:\n' + after.stdout);
} finally {
  rmSync(fixture, { recursive: true, force: true });
}

Observed command selection:

env PATH only:
/mingw64/bin/curl
/usr/bin/sleep

PATH after Bash startup:
<fixture POSIX path>/curl
<fixture POSIX path>/sleep

Additional root-cause evidence

A separate probe executed the unchanged Wait for CI on the immutable release commit script from the current workflow, using synthetic gh responses and the same no-op Node sleep fixture:

Fixture arrangement Result Poll calls Duration
Fixture PATH supplied before bin\bash.exe startup ETIMEDOUT; no missing-CI diagnostic 8 of 30 15.0 s
Same arrangement, diagnostic-only 60 s observation ETIMEDOUT; no missing-CI diagnostic 29 of 30 60.0 s
Override sleep with a no-op Bash function Expected exit 1 and missing-CI diagnostic 30 of 30 2.7 s
Prepend fixture PATH after Bash startup; retain Node command stubs Expected exit 1 and missing-CI diagnostic 30 of 30 5.4 s

This isolates command resolution, rather than slow Node process startup or a production release-gate timeout. The 60-second run was only a diagnostic observation; no checked-in timeout was changed.

Suggested scope / existing related work

tests/test-script.test.ts already handles this boundary by passing the fixture directory as a quoted positional argument and prepending it after Bash startup. The affected fixtures could use the same approach, with assertions that curl/sleep resolve to the intended stubs. Preserve all current healthy-daemon, immutable-SHA, failed-CI, and missing-CI assertions; do not skip Windows tests, increase their timeout to hide real sleeps, or change production launcher/release behavior.

Thanks for #2902, which fixes the process-exit race reported in #2894. I verified that fix by running all four mock-launcher cases with usr\bin\bash.exe. This report concerns the separate command-selection boundary exposed by the documented PowerShell bin\bash.exe setup, not a request to reopen or revert that fix. #2041 already corrected the analogous boundary in tests/test-script.test.ts; #2651 concerns the different unhealthy-daemon fixture.

Searched current open issues/PRs and historical reports for Windows PATH, bash.exe, fixture PATH, and release/missing-CI timeouts; no equivalent open issue or PR was found. No tracked SDK, generated, test, workflow, dependency, or configuration files were modified.

Additional verification: pnpm exec tsc --noEmit -p tsconfig.json and pnpm lint both pass on this revision.

Lingua principale
TypeScript
Stelle
11.3k
Fork
1.6k
Merge medio
12h 45m
PR unite (30g)
201

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di openai/openai-node

Tutte le issue di openai/openai-node

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.