From 65a5036506ac1bc35a98563d8b23cf38dceb0983 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 21 Sep 2026 13:45:55 +0000 Subject: [PATCH] test: give t/ its own git identity and run the whole tree in CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two coupled gaps in the t/ harness. The suite supplied no git identity of its own. t/test-lib.sh left it to whoever ran the tests, and several tests commit without configuring one per repository, so on a machine with no global identity — a fresh runner, a container — they died with "unable to auto-detect email address". .github/workflows/t9-suite.yml papered over that with a `git config --global` step, which meant the suite could not be run anywhere else without the same manual setup. t/test-lib.sh now points HOME at its own trash directory and writes a .gitconfig there. A global config file rather than GIT_AUTHOR_* / GIT_COMMITTER_*: those env vars outrank repository config and would silently override the many tests that set `git config user.email` in their own repositories, whereas a global file keeps the normal precedence. Redirecting HOME also stops a developer's real ~/.gitconfig from leaking into a run. t/test-lib-e2e.sh already did the equivalent. That unblocks the second gap: the only task touching t/ filtered on `t9`, so the 30 t0xxx files had no CI job at all — the same structural blind spot that let t9014, t90010 and a t9007 assertion sit broken for months. The task now runs the tree unfiltered and is renamed test-t, with the workflow renamed to match and its identity step dropped as redundant. All 63 files (t0 30, t1 1, t3 10, t7 1, t9 21) pass under `env -i` with an empty HOME and no git identity configured anywhere, in 54s against a prebuilt binary — the job's ~14 minutes is the release build, which is paid once either way. The t0011/t0012/t0013/t0015 "random" tests drive a seeded LCG from fixed seeds, so they are deterministic and carry no flake risk. Fixes #202 Fixes #204 Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01VDVUJHu38YtVAr6sKZtRDB --- .../workflows/{t9-suite.yml => t-suite.yml} | 33 +++++++++---------- Taskfile.pkl | 16 ++++----- docs/git-compatibility.md | 2 +- t/README.md | 2 +- t/test-lib.sh | 19 +++++++++++ 5 files changed, 45 insertions(+), 27 deletions(-) rename .github/workflows/{t9-suite.yml => t-suite.yml} (60%) diff --git a/.github/workflows/t9-suite.yml b/.github/workflows/t-suite.yml similarity index 60% rename from .github/workflows/t9-suite.yml rename to .github/workflows/t-suite.yml index 658aeee4..dbfddc00 100644 --- a/.github/workflows/t9-suite.yml +++ b/.github/workflows/t-suite.yml @@ -1,10 +1,13 @@ -name: t9 Suite +name: t Suite # The t/ integration tests had no CI job at all: ci.yml's `select` skips its -# jobs for a diff that only touches t/, and nothing invoked the test-subdir -# task. That blind spot let t9014, t90010 and a t9007 assertion sit broken for +# jobs for a diff that only touches t/, and nothing invoked the task that runs +# them. That blind spot let t9014, t90010 and a t9007 assertion sit broken for # months. This workflow is deliberately ungated — it runs on every pull # request, like js-build.yml — so the suite cannot go dark again. +# +# It runs the whole t/ tree, not one range: t0xxx went uncovered for the same +# structural reason t9 did, and a filter here is exactly how that happens. on: push: @@ -17,7 +20,7 @@ permissions: contents: read jobs: - t9-suite: + t-suite: runs-on: ubuntu-latest timeout-minutes: 90 steps: @@ -46,16 +49,12 @@ jobs: - name: Moon update run: moon update - # t/test-lib.sh sets no identity of its own, and several tests commit - # without configuring one per repository, so they rely on a global it - # never establishes. Without this the suite dies on "unable to - # auto-detect email address". - - name: Configure git identity - run: | - git config --global user.name "Bit Test" - git config --global user.email "test@example.com" - - # Builds the release binary at the path t/test-lib.sh looks for, via the - # test-subdir task's build dependency. - - name: Run t9 suite - run: pkf run test-subdir + # No `git config --global user.name/user.email` step: t/test-lib.sh and + # t/test-lib-e2e.sh each point HOME at their own trash directory and + # establish an identity of their own, so the suite no longer depends on + # the runner's git configuration. + + # Builds the release binary at the path the test libs look for, via the + # test-t task's build dependency. + - name: Run t/ suite + run: pkf run test-t diff --git a/Taskfile.pkl b/Taskfile.pkl index 15649b0b..a1e4e844 100644 --- a/Taskfile.pkl +++ b/Taskfile.pkl @@ -330,13 +330,13 @@ local e2e: Task = new { cmd = "bash e2e/run-tests.sh" } -local testSubdir: Task = new { - name = "test-subdir" - description = "t9 integration tests: subdir clone/push, workspace, transports" - // The filter is a substring match, so `t9` covers the whole t9 range in one - // pass — `t900` alone skipped t9011-t9021, which is how several of these - // tests stayed broken unnoticed. - cmd = "bash t/run-tests.sh t9" +local testT: Task = new { + name = "test-t" + description = "All t/ integration tests (t0 core, t1/t3/t7, t9 subdir/workspace/transport)" + // No filter: every t/ range runs. A filter is how these tests went dark + // before — `t900` skipped t9011-t9021, and widening it to `t9` still left + // the 30 t0xxx files with no CI job at all. + cmd = "bash t/run-tests.sh" deps { build } } @@ -717,7 +717,7 @@ tasks { buildPagesDemo e2e - testSubdir + testT testDistributed testAi diff --git a/docs/git-compatibility.md b/docs/git-compatibility.md index 009e4327..217dcfe9 100644 --- a/docs/git-compatibility.md +++ b/docs/git-compatibility.md @@ -175,7 +175,7 @@ Full upstream run (`pkf run git-t`) summary on macOS (2026-02-07): - `pkf run check`: pass - `pkf run test`: pass (`js/lib 215 pass`, `native 811 pass`) - `pkf run e2e` (`t/run-tests.sh t00`): pass -- `pkf run test-subdir` (`t/run-tests.sh t900`): pass +- `pkf run test-t` (`t/run-tests.sh`, all 63 files): pass - `pkf run git-t-allowlist`: pass (`success 24,279 / failed 0 / broken 177`) ## Performance Snapshot (2026-02-12) diff --git a/t/README.md b/t/README.md index c8c913f0..3568652d 100644 --- a/t/README.md +++ b/t/README.md @@ -5,7 +5,7 @@ This directory contains shell-based integration tests for bit, following the Git ## Running Tests ```bash -# Run all tests +# Run all tests (this is what the t-suite CI job runs, via `pkf run test-t`) ./t/run-tests.sh # Run legacy e2e subset (t00xx) diff --git a/t/test-lib.sh b/t/test-lib.sh index 34b89a1c..79784037 100755 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -49,6 +49,25 @@ rm -rf "$TRASH_DIRECTORY" mkdir -p "$TRASH_DIRECTORY" cd "$TRASH_DIRECTORY" || exit 1 +# Give the suite its own git identity instead of borrowing whoever is running +# it. Several tests commit without configuring one per repository, so on a +# machine with no global identity — a fresh runner, a container — they died +# with "unable to auto-detect email address". +# +# This writes a global config under a private HOME rather than exporting +# GIT_AUTHOR_* / GIT_COMMITTER_*: those env vars outrank repository config, +# and would silently override the many tests that set `git config user.email` +# in their own repositories. A global file keeps the normal precedence, so a +# per-repository setting still wins. Pointing HOME here also stops the +# developer's real ~/.gitconfig from leaking into a run. +HOME="$TRASH_DIRECTORY" +export HOME +cat >"$TRASH_DIRECTORY/.gitconfig" <<-EOF + [user] + name = Bit Test + email = test@example.com +EOF + # Cleanup on exit cleanup() { cd "$TEST_DIRECTORY" || exit 1