From b54d98655020dde6f273397ffe2d246d96709018 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Wed, 6 May 2026 23:35:16 -0400 Subject: [PATCH] chore(changeset): add pr: 3216 to build-hooks-atomic-write changeset The changeset parser hard-fails on fragments without a pr: field. Co-Authored-By: Claude Opus 4.7 (1M context) --- .changeset/build-hooks-atomic-write.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.changeset/build-hooks-atomic-write.md b/.changeset/build-hooks-atomic-write.md index e31442123..3b254c9e8 100644 --- a/.changeset/build-hooks-atomic-write.md +++ b/.changeset/build-hooks-atomic-write.md @@ -1,4 +1,5 @@ --- type: Fixed +pr: 3216 --- **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)