From cd0e3e26d6102fc6995184e10ca440d444ca48a5 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Wed, 3 Jun 2026 19:20:55 -0700 Subject: [PATCH] test: prevent Linux-CI git hangs (no prompt/editor/pager) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- .../core/src/__test-utils__/vitest-setup.ts | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/packages/core/src/__test-utils__/vitest-setup.ts b/packages/core/src/__test-utils__/vitest-setup.ts index de895b95f8..431a7768c3 100644 --- a/packages/core/src/__test-utils__/vitest-setup.ts +++ b/packages/core/src/__test-utils__/vitest-setup.ts @@ -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 {