fix(runner): stop re-running files a previous build correctly skipped - #63
Merged
Conversation
Three consecutive `run build` calls over an unchanged file failed on the third. `needsRun` forced a re-run for any `skipped` execution record, but `skipped` means two different things: a cascade skip (an earlier file in the batch failed, so this one never executed) and an `unchanged` skip, which is the recorded outcome of a correct decision. Build 2 skipped and wrote `unchanged`; build 3 read that as "never ran", re-executed, and hit "already exists" on any DDL that is not idempotent. The record then read `failed`, so every later build retried and failed too. Only `pending` placeholders and cascade skips force a run now. An `unchanged` skip falls through to the stale check and checksum comparison, so a genuinely edited file still re-runs. Deterministic, not intermittent — likely the root cause behind #54.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Found while smoke-testing a locally-built binary from
master. Deterministic, 100% reproducible, and it breaks the single most common thing anyone does with this tool: runningrun buildmore than twice.Repro
Empty sqlite DB, one non-idempotent
CREATE TABLE,build.include: [01_tables]:Cause
Tracker.needsRun()(src/core/runner/tracker.ts) forced a re-run for anyskippedexecution record. Butskippedcarries two distinct meanings:skip_reason: 'unchanged'— the recorded outcome of a correct skip. Must not re-run.Upfront placeholders from
createFileRecordsare'pending', not'skipped', so thependinghalf of that condition was already doing the job its comment described. Theskippedhalf was over-broad.So build 2 skipped correctly and wrote
unchanged; build 3 read that as "never ran" and re-executed. Once it failed, the record readfailed, and the retry branch made every later build fail too.Fix
Select
skip_reason, and only force a run forpendingor a non-unchangedskip. Anunchangedskip falls through to the existing stale check and checksum comparison — so a genuinely edited file still re-runs.Verified end to end against the built binary:
Likely closes #54
#54 was filed as "
run buildintermittently fails on objects it just created" and explicitly asked to rule double execution in or out at the source. It isn't intermittent — it depends on how many times that file had already been built. The reporter's read ("for the error to fire on an empty database, that statement has to have run before") was correct.I'd let the reporter confirm against their MSSQL tree before closing it outright, since their repro had a different shape (failure inside a first build over 9 phase directories).
Verified: lint, typecheck, build clean. All four CI groups against live pg/mysql/mssql — 2592 / 122 / 476 / 631 = 3821 pass, 0 fail. 6 new tracker tests; with the buggy condition restored, the regression test fails, along with the checksum and stale fall-through cases — confirming those paths were unreachable before.