Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,16 +174,17 @@ jobs:

- name: Install bats-core + jq
run: |
# GNU parallel lets bats run tests side by side (--jobs, below).
if [[ "$RUNNER_OS" == "macOS" ]]; then
brew install bats-core jq
brew install bats-core jq parallel
elif [[ "$RUNNER_OS" == "Windows" ]]; then
# bats-core ships an npm package that drops a Windows-compatible
# bats wrapper on PATH. jq is preinstalled on windows-latest.
npm install -g bats
jq --version
else
sudo apt-get update
sudo apt-get install -y bats jq
sudo apt-get install -y bats jq parallel
fi

- name: Verify dependencies
Expand All @@ -198,8 +199,20 @@ jobs:
git config --global user.email "ci@example.com"
git config --global user.name "CI"

# One job per CPU (serial on the Mac took 48 min for 2055 tests,
# 2026-10-29; 14 jobs took 4 min). Serial when GNU parallel is absent.
- name: Run test suite
run: bats tests/
run: |
jobs=1
if command -v parallel >/dev/null 2>&1; then
jobs="$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 2)"
fi
echo "bats jobs: $jobs"
if (( jobs > 1 )); then
bats --jobs "$jobs" tests/
else
bats tests/
fi

shellcheck:
needs: changes
Expand Down
9 changes: 7 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ most things can ship quickly if they fit the design.
1. **Fork** the repo and clone locally
2. **Branch** off `main`: `git checkout -b your-branch-name`
3. **Make changes** — see "What kinds of contributions are welcome" below
4. **Run tests**: `bats tests/` (install via `brew install bats-core` if needed)
4. **Run tests**: `bats --jobs 8 tests/` (install via `brew install bats-core parallel` if needed; plain `bats tests/` runs the same suite serially, about 10x slower)
5. **Open a PR** against `main` with a description of the change

## What kinds of contributions are welcome
Expand Down Expand Up @@ -89,10 +89,15 @@ tests/ bats-core test suite
The bats test suite is the primary safety net:

```bash
bats tests/ # run all
bats --jobs 8 tests/ # run all, 8 at a time (needs GNU parallel)
bats tests/ # run all, one at a time
bats tests/canonicalize.bats # run one file
```

Tests run side by side under `--jobs`, so a test keeps its state in its own
temp dirs (`fi_setup_tmp`, `$BATS_TEST_TMPDIR`) and never kills processes by a
pattern another test could also match.

When adding code, add tests. Existing files in `tests/` are good
reference — they cover lib functions, CLI subcommands, and hooks.

Expand Down
3 changes: 2 additions & 1 deletion docs/found-issues.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,5 @@ Maintained automatically by Claude. See <https://github.com/AltDoug/found-issues
- [fixed] 2026-10-27 lib/autofix-ship.sh:658 — the 3.10.7 squash rebuild runs only after GitHub's AutomaticBaseChangeSucceededEvent, which needs the landing branch deleted; in a repo with delete_branch_on_merge off the landing branch survives its squash merge, so a fix PR still merges into that dead branch and never reaches the default branch. Seen on ByteTechSoftwares/sayciao#320 (base gsd/phase-24-resume squash-merged into main as #318 on 2026-10-25, branch kept, 49 ahead / 6 behind main) (suggested: before merging, if the base has a merged PR into the default branch whose squash is not an ancestor-carrier of the base tip, retarget with gh pr edit --base and reuse _fi_af_mwg_squashed with that PR as #M) (decide: When a fix PR's landing branch was squash-merged into the default branch but not deleted [no GitHub retarget], should merge-when-green retarget the PR to the default branch and rebuild it there, or stop and report?) (PR: AltDoug/found-issues#292) (fixed: 2026-10-27)
- [fixed] 2026-10-27 tests/autofix-sweep.bats:1067 — 'a continuation's PR leaves the PR branch ledger alone' flaked on the Mac 2026-10-27 with status 141: git log ... | grep -q under pipefail, grep -q exits on the first match and git log dies of SIGPIPE (suggested: capture the log into a variable first, then grep it, as other tests do) (fix: small) (PR: AltDoug/found-issues#292) (fixed: 2026-10-27)
- [open] 2026-10-29 lib/sync.sh:770 — SessionStart sync still writes the ledger on a pull-only clone through auto-archive (and merged-PR closures): measured 2026-10-29 on a main-only agent-config clone, sync moved 5 [fixed] entries to found-issues-archive.md; git refuses a later pull --ff-only even when upstream made the byte-identical edit, so the clone's update path breaks whenever upstream commits the same archive (suggested: read-only sync mode for consumer clones) (decided: build the read-only sync mode: a per-clone git config key plus an env override; picked over keeping the deploy workaround and over doing both [operator, 2026-10-29, via agent-config: Mods Dougstation]) (PR: AltDoug/found-issues#295)
- [open] 2026-10-29 tests/autofix-sweep.bats — full bats suite runs serially and keeps growing: 24m08s on 2026-10-07, ~40 min on 2026-10-11, 48 min for 2048 tests on 2026-10-29 (this Mac); each autofix-* test builds a real repo + bare remote + worktree and runs the pipeline (measured 3.5-7.2 s per sweep test), and the fix-ship gate is 60 min (FOUND_ISSUES_FIX_SHIP_TIMEOUT_SECS), so headroom fell from ~20 to ~12 min (suggested: run bats --jobs N with GNU parallel, each test already uses its own mktemp dir; then cache per-file fixtures if still slow) (decided: fix it after 3.11.0 ships: run the suite in parallel with bats --jobs [GNU parallel as dev + CI dependency], then per-file fixture caching if still slow [operator, 2026-10-29])
- [open] 2026-10-29 tests/autofix-sweep.bats — full bats suite runs serially and keeps growing: 24m08s on 2026-10-07, ~40 min on 2026-10-11, 48 min for 2048 tests on 2026-10-29 (this Mac); each autofix-* test builds a real repo + bare remote + worktree and runs the pipeline (measured 3.5-7.2 s per sweep test), and the fix-ship gate is 60 min (FOUND_ISSUES_FIX_SHIP_TIMEOUT_SECS), so headroom fell from ~20 to ~12 min (suggested: run bats --jobs N with GNU parallel, each test already uses its own mktemp dir; then cache per-file fixtures if still slow) (decided: fix it after 3.11.0 ships: run the suite in parallel with bats --jobs [GNU parallel as dev + CI dependency], then per-file fixture caching if still slow [operator, 2026-10-29]) (PR: AltDoug/found-issues#296)
- [open] 2026-10-29 tests/helpers.bash:25 — tests that keep the real HOME write the operator's real ~/.cache/found-issues: measured 2026-10-29, ~/.cache/found-issues/mode_foo_bar was rewritten at 23:11 by a suite run (foo/bar is only a test fixture slug); one shared file across tests that run side by side under bats --jobs can also hand one test another's cached mode (suggested: per-test HOME in helpers, with git identity via GIT_AUTHOR_*/GIT_COMMITTER_* env so commits still work, or point XDG_CACHE_HOME at $BATS_TEST_TMPDIR in the files that do not set HOME) (fix: medium)
11 changes: 7 additions & 4 deletions tests/autofix-cancel.bats
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ setup() {
fi_setup_tmp; fi_af_fixture; fi_use_standins; fi_af_queue_fixture
ST="$FI_AF_ST"
export GH_MOCK_TRACE="$TMP/gh.trace"
# Sleep lengths unique to this test process, so the teardown below kills
# only this test's sleeps, never those of a test running beside it.
NAP_ENGINE="9${$}3" NAP_FOREIGN="9${$}4"
}
# A failing cancel must not leave the stand-in sleeping for an hour.
teardown() { pkill -f 'sleep 471[34]' 2>/dev/null || true; fi_teardown_tmp; }
teardown() { pkill -f "^sleep (${NAP_ENGINE}|${NAP_FOREIGN})\$" 2>/dev/null || true; fi_teardown_tmp; }

# The engine child's group, once it runs: claim's base test run (3.2.1) has
# its own, already finished, child group first.
Expand Down Expand Up @@ -77,7 +80,7 @@ wait_engine() {
}

@test "autofix cancel: an A run and its engine child are stopped" {
export FI_STANDIN_SLEEP=4713
export FI_STANDIN_SLEEP="$NAP_ENGINE"
"$FI_BIN" autofix run "$ID" --engine claude >/dev/null 2>&1 &
rpid=$!
wait_engine
Expand All @@ -101,7 +104,7 @@ wait_engine() {
}

@test "autofix cancel: a pid that is not an autofix run is never signalled" {
sleep 4714 & spid=$!
sleep "$NAP_FOREIGN" & spid=$!
wt="$("$FI_BIN" autofix claim "$ID")"
printf 'pid=%s\n' "$spid" >>"$ST/running/$ID"
run "$FI_BIN" autofix cancel "$ID"
Expand All @@ -111,7 +114,7 @@ wait_engine() {
}

@test "autofix cancel: a stale running item never signals the run that moved on" {
export FI_STANDIN_SLEEP=4713
export FI_STANDIN_SLEEP="$NAP_ENGINE"
"$FI_BIN" autofix run "$ID" --engine claude >/dev/null 2>&1 &
rpid=$!
wait_engine
Expand Down
6 changes: 4 additions & 2 deletions tests/cli-sync-default-branch.bats
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ setup() {
fi_setup_tmp
fi_init_git
fi_use_gh_shim
# The default-branch cache lives under XDG_CACHE_HOME: give each test its
# own, inside $TMP. A shared ~/.cache plus a teardown that emptied it let
# one test delete another's cache when they ran side by side (bats --jobs).
export XDG_CACHE_HOME="$TMP/xdg-cache"
}

teardown() {
fi_teardown_tmp
# Clean up any cache files this test created (they live globally in ~/.cache)
rm -rf ~/.cache/found-issues/default-branch-* 2>/dev/null || true
}

@test "sync: uses gh repo view fallback when origin/HEAD is unset and gh available" {
Expand Down
2 changes: 1 addition & 1 deletion tests/fix-batch8-long-root.bats
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ setup() {
fi_setup_tmp
TMP_TOP="$TMP"
}
teardown() { pkill -f 'sleep 471[34]' 2>/dev/null || true; TMP="$TMP_TOP"; fi_teardown_tmp; }
teardown() { TMP="$TMP_TOP"; fi_teardown_tmp; }

long_dir() { printf "$1%.0s" $(seq 1 100); }

Expand Down
5 changes: 4 additions & 1 deletion tests/helpers.bash
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ export FOUND_ISSUES_SEGMENT_AUTOSYNC=off

# Segment renders write a cache (lib/segment-cache.sh) under the cache dir;
# keep it out of the real ~/.cache. Tests that inspect it set their own.
export FOUND_ISSUES_CACHE_DIR="${BATS_RUN_TMPDIR:-${TMPDIR:-/tmp}}/fi-test-cache"
# One per test (BATS_TEST_TMPDIR exists when this file loads): auto-fix keeps
# its run logs there (FI_AF_RUNS), and tests running in parallel (bats
# --jobs) shared and mixed one another's logs.
export FOUND_ISSUES_CACHE_DIR="${BATS_TEST_TMPDIR:-${BATS_RUN_TMPDIR:-${TMPDIR:-/tmp}}}/fi-test-cache"

# A suite started inside an auto-fix run inherits FOUND_ISSUES_AUTOFIX_CHILD=1,
# which makes session-start take its headless path and fails every test of
Expand Down
Loading