scripts/build-hooks.js used fs.copyFileSync (truncate-then-write, non-atomic). Under --test-concurrency=4, multiple builder invocations raced; a parallel install.js subprocess could readFileSync between truncate and write and observe an empty file, then write that emptiness into the install target. Surfaced as the release-blocking bug-2136-sh-hook-version part 4 failure on main even though the same SHA passed every install-smoke matrix entry. Fix: stage outputs to hooks/.dist-staging/ then fs.renameSync into hooks/dist/. POSIX rename(2) is atomic, so concurrent readers always observe a complete file. The existing bug-2136 part 4 test locks the post-fix invariant. Failing run: https://github.com/gsd-build/get-shit-done/actions/runs/25472202941/job/74738276687 Closes #3214 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1.3 KiB
type
| type |
|---|
| Fixed |
Atomic writes in scripts/build-hooks.js to fix flaky release CI — nine test files invoke build-hooks.js from their before() hooks, and scripts/run-tests.cjs runs test files with --test-concurrency=4, so multiple builders raced to rewrite the same files in hooks/dist/. fs.copyFileSync(src, dest) truncates dest then writes it; a parallel bin/install.js subprocess (spawned by another install test) could fs.readFileSync between the truncate and the write and observe an empty file. install.js then wrote that empty content into the install target, so installed .sh hooks lacked their # gsd-hook-version: header. This surfaced as the release-blocking failure in tests/bug-2136-sh-hook-version.test.cjs part 4 even though the same SHA passed on every other Node-22/Node-24 install-smoke matrix run. build-hooks.js now stages each output to a sibling hooks/.dist-staging/ directory (same filesystem as hooks/dist/) and uses fs.renameSync to swap into place — POSIX rename(2) is atomic, so concurrent readers always observe a complete file. The existing tests/bug-2136-sh-hook-version.test.cjs part 4 already locks the post-fix invariant. (Failing run: https://github.com/gsd-build/get-shit-done/actions/runs/25472202941/job/74738276687)