test: prevent Linux-CI git hangs (no prompt/editor/pager)

Extends the test-setup git hardening. The engine --shard=2/2 worktree-heavy
reliability suite was hanging in CI (progressing healthily, then ~2 min of
silence before the job timeout killed it with no test failure) — the signature
of a git command blocking on an interactive prompt. A dev macOS git config
suppresses these; a bare Linux CI git does not. Disable terminal credential
prompts (GIT_TERMINAL_PROMPT=0), the editor (GIT_EDITOR=true), and the pager
(GIT_PAGER=cat) for every test process so no git invocation can block on a TTY.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-06-03 19:20:55 -07:00
parent 3432e0615c
commit cd0e3e26d6

View File

@@ -69,18 +69,33 @@ const BLOCKED_TEST_CLI_PATTERN =
const originalCwd = process.cwd.bind(process);
// Pin `git init` to the `main` branch for every test process. Git defaults the
// initial branch to `master` unless `init.defaultBranch` is set — true on Linux
// CI runners but usually overridden to `main` on developer macOS machines. That
// host gap silently broke git-worktree tests that assume `main` (e.g. the
// shared-branch-group reliability suite) in CI only. These GIT_CONFIG_* env
// vars apply the setting to all child git invocations without mutating the
// developer's global config. Appended (not clobbered) if a count already exists.
// Harden git for every test process against host/CI differences that silently
// broke git-worktree tests in CI only (they pass on developer macOS machines):
//
// 1. Pin `git init` to the `main` branch. Git defaults the initial branch to
// `master` unless `init.defaultBranch` is set — true on Linux CI runners
// but usually `main` on dev machines. The gap broke worktree tests that
// assume `main` (e.g. the shared-branch-group reliability suite).
// 2. Never block on an interactive prompt. A Linux CI git can hang forever
// waiting on a credential/editor/pager prompt where a dev's git config
// suppresses it — the suite then runs to the job timeout and is killed
// with no test failure. Disable terminal prompts, the editor, and pagers.
//
// GIT_CONFIG_* applies config to all child git invocations without mutating the
// developer's global config; the prompt/editor/pager env vars are inherited by
// every spawned git. Config entries are appended, not clobbered.
(() => {
const existing = Number.parseInt(process.env.GIT_CONFIG_COUNT ?? "0", 10) || 0;
process.env[`GIT_CONFIG_KEY_${existing}`] = "init.defaultBranch";
process.env[`GIT_CONFIG_VALUE_${existing}`] = "main";
process.env.GIT_CONFIG_COUNT = String(existing + 1);
const base = Number.parseInt(process.env.GIT_CONFIG_COUNT ?? "0", 10) || 0;
const entries: Array<[string, string]> = [["init.defaultBranch", "main"]];
entries.forEach(([key, value], i) => {
process.env[`GIT_CONFIG_KEY_${base + i}`] = key;
process.env[`GIT_CONFIG_VALUE_${base + i}`] = value;
});
process.env.GIT_CONFIG_COUNT = String(base + entries.length);
process.env.GIT_TERMINAL_PROMPT ??= "0"; // never prompt for credentials
process.env.GIT_EDITOR ??= "true"; // merges/rebases never open an editor
process.env.GIT_PAGER ??= "cat"; // no pager waiting on a TTY
})();
function ensureValidCwd(): string {