ci: the eval image installs zsh, and the macOS lane sources the Codex probe from zsh

Dockerfile.ci adds zsh so the sourced-helper guard runs (and fails loudly
when zsh is missing) inside the eval container too. The macOS named
regressions job sources bin/gstack-codex-probe from zsh in an unrelated
directory and runs _gstack_codex_select_model exec (no paid call), then runs
the sourced-helper guard on the macOS runner. A free test pins both lanes and
runs the macOS step's script locally.
This commit is contained in:
garrytan committed 2026-10-06 20:43:44 +00:00
1 parent 3542322819
commit fa79a3071e
3 files changed
+32 -3

No files matched your search

@@ -285,4 +285,23 @@ describe('#3024: sourced helpers work under bash and zsh', () => {
fs.rmSync(empty, { recursive: true, force: true });
}
});
test('CI keeps zsh: the free lane and the eval image install it, and the macOS lane sources the probe from zsh', () => {
const workflow = Bun.YAML.parse(fs.readFileSync(path.join(ROOT, '.github/workflows/free-tests.yml'), 'utf8')) as any;
const runs = (job: string) => (workflow.jobs[job].steps as any[]).map(step => String(step.run ?? '')).join('\n');
expect(runs('free-suite')).toMatch(/apt-get install[^\n]*\bzsh\b/);
expect(fs.readFileSync(path.join(ROOT, '.github/docker/Dockerfile.ci'), 'utf8')).toMatch(/apt-get install -y --no-install-recommends \\\n[^\n]*\bzsh\b/);
const mac = workflow.jobs['macos-named-regressions'];
expect(mac['runs-on']).toMatch(/^macos-/);
const step = (mac.steps as any[]).find(s => String(s.run ?? '').includes('_gstack_codex_select_model exec'));
expect(step?.run).toContain(`zsh -c 'source "$GITHUB_WORKSPACE/bin/gstack-codex-probe" && _gstack_codex_select_model exec'`);
expect(runs('macos-named-regressions')).toContain('test/regression-issue3024-zsh-sourced-helpers.test.ts');
if (skipShell('zsh')) return;
const codexHome = fs.mkdtempSync(path.join(os.tmpdir(), 'zsh-helpers-ci-step-'));
try {
const r = run('bash', step.run, { GITHUB_WORKSPACE: ROOT, CODEX_HOME: codexHome });
expect(r.code).toBe(0);
expect(r.stdout).toMatch(/CODEX_MODEL: \S+ \(exec; source: /);
} finally { fs.rmSync(codexHome, { recursive: true, force: true }); }
});
});