← ClaudeAtlas

reproducing-ci-locallylisted

Run the CI gate on your machine so it agrees with the runner — deriving the exact command, paths, markers, and env from the workflow file instead of the Makefile, unblocking gate steps that short-circuit and hide the next failure, pinning the linter version CI resolves, and confirming the run is green instead of explaining a red job away. Use when a check passes locally but fails in CI (or the reverse), when a lint/format job goes red on an untouched file, when setting up a local dev loop for an unfamiliar repo, or before pushing a branch you expect to merge.
AleksandarBisevac/claude-plugins · ★ 4 · Code & Development · score 77
Install: claude install-skill AleksandarBisevac/claude-plugins
# Reproducing CI Locally A local check is only useful if it runs the same thing the runner runs. Most "green locally, red in CI" failures are not bugs in the code — they are a difference between two commands: different paths, different test markers, different env, a different linter version, or a different interpreter. The fix is mechanical: **derive the local command from the workflow file**, not from the Makefile, not from habit, not from what the last repo used. ## Read the workflow before you run anything The workflow is the contract. The Makefile is a convenience that drifts from it. ```bash # What the gate actually is, in order sed -n '/jobs:/,$p' .github/workflows/ci.yml # Every command CI runs, across all workflows grep -rn "run:" .github/workflows/ ``` Copy out four things, verbatim: 1. **The commands and their order.** 2. **The paths each command is scoped to** (`ruff check app tests scripts` is not `ruff check .`). 3. **Test selection** — marker expressions, `-k` filters, which suites are excluded. 4. **The `env:` block**, and the runtime/toolchain versions in `setup-*` steps. Each of those four is a distinct way to get a wrong answer locally. **Paths.** If CI lints `app tests scripts` and you run `ruff check .`, you get findings from directories CI never looks at — a red that isn't a merge blocker and shouldn't be "fixed" in an unrelated PR. Run it the narrow way to reproduce the gate; run it the wide way only when you're deliberately auditing. **Mar