What happened
During the 1.7.3 release, check (24) failed on the canonical pull request for
#1154 with one test:
FAIL test/demo.test.ts > commitlore demo > temporary directory is gone after a simulated crash (safety property)
AssertionError: expected [ 'commitlore-demo-ipo06W' ] to deeply equal []
So the outcome is not a property of the tree. The merged change touched
core/squash.ts and core/stale.ts only, neither of which is on the demo's
crash path: runDemo throws at the crashTest point immediately after the
predecessor commit, before any squash code runs.
Why it is invisible
src/commands/demo.ts cleans up best-effort:
const cleanup = (): void => {
if (tmpDir !== undefined) {
try {
rmSync(tmpDir, { recursive: true, force: true });
} catch {
// Best-effort cleanup
}
tmpDir = undefined;
}
};
The catch {} is deliberate for the signal path — a handler must not throw —
but it means the one piece of evidence that would name the cause (the errno:
EBUSY, ENOTEMPTY, a git process still holding a descriptor) is discarded.
The test then reports the symptom, the directory, and nothing about why.
A flake in a test whose name says "safety property" is worse than an ordinary
flake: the next person cannot tell a cleanup race from a real cleanup failure,
which is exactly the distinction the test exists to make.
What would settle it
- Give
rmSync the retry it already supports — maxRetries with a small
retryDelay — which is the standard answer for a transient hold on a
directory tree.
- Keep the swallow, but record what was swallowed: the last cleanup error in a
variable the caller can read, or a line on stderr outside the asserted
output. Without it, the next occurrence yields the same unreadable report.
Not fixed in 1.7.3 on purpose: the cause is unknown, and shipping a retry as if
it were the fix would make an untested hypothesis look like a verified one.
What happened
During the 1.7.3 release,
check (24)failed on the canonical pull request for#1154 with one test:
check (24))check (22.23.2)passed in the same run, on the same commit.passed locally on that commit.
So the outcome is not a property of the tree. The merged change touched
core/squash.tsandcore/stale.tsonly, neither of which is on the demo'scrash path:
runDemothrows at thecrashTestpoint immediately after thepredecessor commit, before any squash code runs.
Why it is invisible
src/commands/demo.tscleans up best-effort:The
catch {}is deliberate for the signal path — a handler must not throw —but it means the one piece of evidence that would name the cause (the errno:
EBUSY,ENOTEMPTY, a git process still holding a descriptor) is discarded.The test then reports the symptom, the directory, and nothing about why.
A flake in a test whose name says "safety property" is worse than an ordinary
flake: the next person cannot tell a cleanup race from a real cleanup failure,
which is exactly the distinction the test exists to make.
What would settle it
rmSyncthe retry it already supports —maxRetrieswith a smallretryDelay— which is the standard answer for a transient hold on adirectory tree.
variable the caller can read, or a line on stderr outside the asserted
output. Without it, the next occurrence yields the same unreadable report.
Not fixed in 1.7.3 on purpose: the cause is unknown, and shipping a retry as if
it were the fix would make an untested hypothesis look like a verified one.