Skip to content

test(source-control): prune_babysit_worktrees fixtures do not disable commit signing, so 17 tests error on any signing machine #2358

Description

@kyle-sexton

tests/test_prune_babysit_worktrees.py's repo fixture sets a throwaway identity but not commit.gpgsign false. On any machine with commit.gpgsign = true globally — the default for anyone who signs — there is no secret key for the fixture identity, every fixture commit fails, and 17 of the suite's 45 tests error out.

Reproduced

Machine has commit.gpgsign true and gpg.program set globally. At main (312d7a6a merge-base), with no local edits:

$ cd plugins/source-control/skills/babysit-prs/scripts
$ python3 -m unittest tests.test_prune_babysit_worktrees
Ran 45 tests in 11.876s
FAILED (errors=17)

Every one of the 17 fails the same way, in fixture setup rather than in an assertion:

Traceback (most recent call last):
  File ".../tests/test_prune_babysit_worktrees.py", line 205, in test_a_live_linked_worktree_is_not_an_orphan
    main = make_repo(tmp)
  File ".../tests/test_prune_babysit_worktrees.py", line 55, in make_repo
    git("-C", str(main), "commit", "-q", "--allow-empty", "-m", "init")

The underlying git error:

error: gpg failed to sign the data:
gpg: skipped "t <t@t>": No secret key
gpg: signing failed: No secret key

The site

tests/test_prune_babysit_worktrees.py:48-56make_repo, and the sibling make_bare_hub below it:

def make_repo(tmp: pathlib.Path) -> pathlib.Path:
    """A one-commit repository with committer identity set locally."""
    main = tmp / "mainrepo"
    main.mkdir()
    git("init", "-q", str(main))
    git("-C", str(main), "config", "user.email", "t@t")
    git("-C", str(main), "config", "user.name", "t")
    git("-C", str(main), "commit", "-q", "--allow-empty", "-m", "init")   # <-- signs, and fails
    return main

The docstring already says "committer identity set locally" — signing configuration is the half it misses.

Why this is worth fixing rather than shrugging at

The failure does not look like an environment problem. Fixture setup dies, so the creation cases error while every case that asserts a refusal still passes — a suite reporting "17 errors, 28 pass" reads as a real regression in the code under test. A reader who does not open the traceback will go hunting in prune_babysit_worktrees.py, which is fine. I hit exactly this shape twice in #2309 and lost time to it the first time before recognising it.

CI does not catch it because GitHub runners do not sign by default, so this only ever bites a contributor on their own machine — the worst place for a false regression signal.

Fix

One repo-local line per fixture repo, on a directory the fixture itself just created:

git("-C", str(main), "config", "commit.gpgsign", "false")

Prefer routing through the shared helper #2333 just added. scripts/test-git-helpers.sh already encodes this correctly (git_test_config "$dir" config commit.gpgsign false, and -c commit.gpgsign=false on its init path), so the Python fixture should adopt the same contract rather than open-code a third variant. That also keeps this from recurring in the next Python fixture.

Note the scope constraint from #2162, which is satisfied here: this writes repo-local config into a directory the fixture just created under tmp, never into a caller-supplied or ambient directory. That is the same shape the shell suites use.

Prior art in this exact class

Same defect, same remedy, already fixed twice in #2309 (source-control 0.52.0):

  • hooks/worktree-create-gate.test.shmkrepo
  • scripts/worktree-create.test.sh — both fixture sites; that suite went 94/154 → 154/154 on this machine

This is the third instance. Fixing it and pointing all three at the shared helper would close the class.

Separately observed, NOT filed here

The same full-suite run also shows 3 failures in tests/test_guards.py (merge.wrapper-reaches-failclosed-cli, resolve.wrapper-reaches-failclosed-cli, resolve.wrapper-filters-nothing). Those are not this bug and I am not claiming they are a defect: the child process dies during interpreter startup (from dataclasses import dataclassimport inspect → truncated), yielding exit 1 where the guard row expects 3. That looks environment-specific to this box (Python 3.14 on Windows via uv), and I did not verify it anywhere else — recorded only so the next person running the full suite here is not surprised by it.

Found by wave-2 lane SC, handoff-inbox batch 4, while verifying #2265's shipped fix at main. Windows, Git Bash, Python 3.14.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions