Problem
tests/unit/release_sandbox_test.sh is the slowest unit test file: ~5.8s (next slowest is 3.3s; average unit file is ~400ms).
Measured cause: it calls release::sandbox::create 6 times, and each call tar-copies the entire working repo into a temp dir:
release::sandbox::create (release.sh:374) runs tar -cf - . from $(pwd) with excludes for .git, node_modules, .release-state, .tasks, tmp
- From the repo root that payload is ~21MB (measured:
tar ... | wc -c = 20,951,040 bytes; tar-side alone takes ~0.46s, plus extraction and a 21MB rm -rf per test)
- Two tests additionally run
release::sandbox::setup_git, which does git init && git add . && git commit over the full 21MB tree
None of the 11 tests need real repo content. They assert:
- a temp dir is created (
SANDBOX_DIR set, dir exists)
- key files are copied (
bashunit, build.sh, CHANGELOG.md)
.git and .release-state are excluded
setup_git initializes a repo with exactly 1 commit
mock_gh / mock_git_push behavior (no sandbox copy involved at all)
Proposed fix
Run release::sandbox::create from a tiny fixture directory instead of the repo root:
- In
set_up_before_script (or a helper), build a throwaway dir (use temp_dir from bashunit's API) containing:
- fake
bashunit, build.sh, CHANGELOG.md files (one line each — the copy test only checks existence)
- a fake
.git/ dir and .release-state/ dir (so the exclusion tests prove exclusion self-contained, instead of depending on the real repo's .git)
- Each test that calls
release::sandbox::create first cds into the fixture dir (the function tars $(pwd)), restoring cwd after — same pattern the tests already use with RELEASE_SCRIPT_DIR
release::sandbox::setup_git works unchanged on the fixture (it is a plain git init/add/commit in $SANDBOX_DIR, release.sh:405)
- The
mock_gh/mock_git_push tests need no change
No production code changes. release.sh stays untouched — this is test-only.
Expected result: ~5.8s → well under 1s (copy payload drops from 21MB to a few KB).
Files
tests/unit/release_sandbox_test.sh — the only file to change
release.sh:374-413 — release::sandbox::create / release::sandbox::setup_git (read-only reference)
Constraints
- Bash 3.0+ compatible test code — but note the file already gates itself to Bash 3.1+ at the top (release.sh uses
+=), so [[ ]] present in this file is tolerated; prefer [ ] for new code per .claude/rules/bash-style.md
- TDD: adjust one test at a time, keep the suite green after each step
- Tests must stay safe under
./bashunit --parallel tests/(unique temp dirs per test — temp_dir handles this)
- Keep cleaning up
$SANDBOX_DIR after each test (the tests already rm -rf it)
Acceptance criteria
Verification commands
time ./bashunit tests/unit/release_sandbox_test.sh
./bashunit tests/ && ./bashunit --parallel tests/
make sa && make lint && shfmt -d .
Problem
tests/unit/release_sandbox_test.shis the slowest unit test file: ~5.8s (next slowest is 3.3s; average unit file is ~400ms).Measured cause: it calls
release::sandbox::create6 times, and each call tar-copies the entire working repo into a temp dir:release::sandbox::create(release.sh:374) runstar -cf - .from$(pwd)with excludes for.git,node_modules,.release-state,.tasks,tmptar ... | wc -c= 20,951,040 bytes; tar-side alone takes ~0.46s, plus extraction and a 21MBrm -rfper test)release::sandbox::setup_git, which doesgit init && git add . && git commitover the full 21MB treeNone of the 11 tests need real repo content. They assert:
SANDBOX_DIRset, dir exists)bashunit,build.sh,CHANGELOG.md).gitand.release-stateare excludedsetup_gitinitializes a repo with exactly 1 commitmock_gh/mock_git_pushbehavior (no sandbox copy involved at all)Proposed fix
Run
release::sandbox::createfrom a tiny fixture directory instead of the repo root:set_up_before_script(or a helper), build a throwaway dir (usetemp_dirfrom bashunit's API) containing:bashunit,build.sh,CHANGELOG.mdfiles (one line each — the copy test only checks existence).git/dir and.release-state/dir (so the exclusion tests prove exclusion self-contained, instead of depending on the real repo's.git)release::sandbox::createfirstcds into the fixture dir (the function tars$(pwd)), restoring cwd after — same pattern the tests already use withRELEASE_SCRIPT_DIRrelease::sandbox::setup_gitworks unchanged on the fixture (it is a plaingit init/add/commitin$SANDBOX_DIR, release.sh:405)mock_gh/mock_git_pushtests need no changeNo production code changes.
release.shstays untouched — this is test-only.Expected result: ~5.8s → well under 1s (copy payload drops from 21MB to a few KB).
Files
tests/unit/release_sandbox_test.sh— the only file to changerelease.sh:374-413—release::sandbox::create/release::sandbox::setup_git(read-only reference)Constraints
+=), so[[ ]]present in this file is tolerated; prefer[ ]for new code per.claude/rules/bash-style.md./bashunit --parallel tests/(unique temp dirs per test —temp_dirhandles this)$SANDBOX_DIRafter each test (the tests alreadyrm -rfit)Acceptance criteria
time ./bashunit tests/unit/release_sandbox_test.sh< 1s (baseline: ~5.8s).git/.release-stateexclusion, git init + 1 commit, gh/git-push mocks).git/.release-statein the fixture (no dependency on repo state)release.sh./bashunit tests/and./bashunit --parallel tests/greenmake sa,make lintpass;shfmt -w .produces no diffVerification commands