goalline / Skip what passed
Skip CI tests that the exact same code already passed
Every time a check runs, goalline keeps a signed receipt tied to the exact code it ran on: the git tree, not the commit. When that same code comes back (a rebase, a re-run, a merge that changes nothing), the gate is skipped and the earlier pass is shown instead.
Run gates through goalline
# Skip the gate when this exact code already passed it
goalline run --gate api-unit --reuse -- npx jest
# Two passes, one on an idle machine, for a flaky browser suite
goalline run --gate browser --reuse --reuse-runs 2 --reuse-idle -- npx playwright test
# Which gates are already proven for the code in this checkout? Nothing is re-run.
goalline verify --require api-unit,browser:2 --idle browser
run exits with the command's own exit code, so it wraps any gate: tests, lint, a build. verify ends with what still has to run, and only that, or Nothing to re-run.
Keyed by the code, not the commit
A receipt is keyed by the content of the code: the git tree. A run on uncommitted work therefore verifies once exactly that work is committed, and a merge whose result equals an already-tested tree is already proven.
What a receipt is
An in-toto statement of type test-result/v0.1 about one git tree, in a DSSE envelope signed with the machine's Ed25519 key. It records what ran (command, exit code, test counts, failed test names, duration), the tree and commit, the Node version, the OS and the lockfile digest, whether the machine was idle, and the full log, gzipped next to it.
A receipt counts only if the signature is valid, the tree matches, the code didn't change during the run, the Node major version matches, any --input still reads the same, a pass that read the real clock hasn't expired, and the result is a clean pass: no failures, no flaky tests, and at least one test ran.
Carrying a pass over changes that can't affect it
With --rules rules.json, a pass can also carry over changes outside what a gate depends on: the file names areas of the repo and the areas each gate depends on, and a changed file in no area re-runs everything. Rules start as a trial: the gate still runs, and goalline trial-report shows whether skipping would have been right. With no disagreement in at least 20 would-be skips, --trust-rules really skips, and verify shows CARRIED, never VERIFIED.
Trust model
- Tamper-evident, not forgery-proof. Everyone on one machine shares one key: an edited receipt fails verification, but anything running as your user can sign.
- A receipt proves a run happened, not that the tests are good. That is what goalpost and prove-red are for.
- Nothing secret is stored. Extra env vars are kept as hashes, and no source code leaves the machine.
Related
- How it works: old tests on new code, the verdicts, and what it can't catch
- Claude Code hook: a Stop hook that won't let the agent finish until it explains a moved test
- GitHub Action: one step in a workflow, with Jest, Vitest or pytest
- prove-red: new tests must fail on the base code first, or they test nothing
- Database inputs: the database schema on the receipt, with --input db=pg
- The clock: which tests read the real clock, and passes that expire
- Benchmark: 31 flags on 400 merged PRs, each with its PR's reason
- Commands: every command and option