test(e2e): keep the spawned entire binary off the real OS keychain · Entire
test(e2e): keep the spawned entire binary off the real OS keychain
2965add→main·
Soph·1mo ago·5 files·+23 added/-3 removed
1ea54e2 added keyring.MockInit() to the cli package TestMain so in-process
tests don't read the developer's keychain. But the e2e suite (run by
mise run test:ci via the canary, and by mise run test:e2e) drives the
REAL entire binary as a subprocess, which MockInit can't touch — so a
credential-resolving flow (e.g. the pre-push hook) still triggers a macOS
keychain unlock prompt. Two stores are reachable: the unconditional
internal/entireclient/tokenstore, and the auth package's legacy keyring
store (auth.NewStore().GetToken fallback in contexts.go), which queries the
keychain even when no token is present.
Neutralize both in the e2e environment:
- Add a shared build:e2e task that builds entire with -tags=authfilestore
(so the auth file backend is compiled in), and point the canary,
roger-roger, and default e2e tasks at it. Production
mise run buildstays untagged. - In e2e TestMain, set ENTIRE_TOKEN_STORE=file/_PATH (covers tokenstore, no tag needed) and ENTIRE_TEST_AUTH_STORE_FILE (covers the auth keyring store under the authfilestore tag), pointing at files in the run's artifact dir. Child processes (the binary, git hooks) inherit these.
With these set, resolveBackendLocked returns a fileStore and chooseBackend returns the file backend, so no keyring/keychain call can occur. Canary verified green.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
6d64e8760acbView transcript
Changes
5
e2e/tests
Mmain_test.go+13
mise-tasks/test/e2e
M_default+1/-1
Mcanary+1/-1
Mroger-roger+1/-1
Mmise.toml+7
24 unmodified lines
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
24 unmodified lines
_ = os.MkdirAll(runDir, 0o755)
testutil.SetRunDir(runDir)
// Route every spawned entire binary (and the git hooks that invoke it) at
// file-backed token stores so e2e never touches the developer's real OS
// keychain. These env vars are inherited by child processes:
// - internal/entireclient/tokenstore honors ENTIRE_TOKEN_STORE/_PATH
// unconditionally (always compiled).
// - the auth package's legacy keyring store honors
// ENTIRE_TEST_AUTH_STORE_FILE only in -tags=authfilestore builds, which
// the build:e2e task produces.
// In-process keyring.MockInit() cannot help here: the binary is a subprocess.
os.Setenv("ENTIRE_TOKEN_STORE", "file")
os.Setenv("ENTIRE_TOKEN_STORE_PATH", filepath.Join(runDir, "e2e-tokenstore.json"))
os.Setenv("ENTIRE_TEST_AUTH_STORE_FILE", filepath.Join(runDir, "e2e-auth-tokens.json"))
// Resolve the entire binary (set by mise run build via E2E_ENTIRE_BIN).
entireBin := entire.BinPath()
if err := ensureHookEntireBinary(entireBin); err != nil {
Me2e/tests/main_test.go+13
9 unmodified lines
10
11
12
13
13
14
15
16
9 unmodified lines
# Build from source with version info unless a pre-built binary is provided.
if [ -z "${E2E_ENTIRE_BIN:-}" ]; then
mise run build
mise run build:e2e
if [ -f "$PWD/entire.exe" ]; then
export E2E_ENTIRE_BIN="$PWD/entire.exe"
else
Mmise-tasks/test/e2e/_default+1/-1
4 unmodified lines
5
6
7
8
8
9
10
11
4 unmodified lines
set -eu
# Build entire CLI
mise run build
mise run build:e2e
export E2E_ENTIRE_BIN="$PWD/entire"
# Build vogon binary
Mmise-tasks/test/e2e/canary+1/-1
6 unmodified lines
7
8
9
10
10
11
12
13
6 unmodified lines
export E2E_AGENT="roger-roger"
# Build entire CLI
mise run build
mise run build:e2e
export E2E_ENTIRE_BIN="$PWD/entire"
# Ensure roger-roger binaries are available on PATH before running E2E tests.
Mmise-tasks/test/e2e/roger-roger+1/-1
18 unmodified lines
19
20
21
22
23
24
25
26
27
28
29
30
31
18 unmodified lines
description = "Run integration tests"
run = "gotestsum --format testname --format-icons text --hide-summary skipped -- -tags=integration,authfilestore ./cmd/entire/cli/integration_test/... ./cmd/entire/cli/auth/..."
[tasks."build:e2e"]
description = "Build the CLI for e2e tests with the file-backed auth store (-tags=authfilestore), so the spawned binary and git hooks never touch the developer's OS keychain"
run = """
go build -tags=authfilestore ./cmd/entire
go build ./cmd/git-remote-entire
"""
[tasks."test:ci"]
description = "Run all tests (unit + integration + E2E canary) with race detection"
run = """