
Reproducing Ci Locally
Run the CI gate on your machine so it agrees with the runner, deriving the exact...
Install
npx skills add kajisho5/ffmpeg-skill --skill reproducing-ci-locally -g -a claude-code -y- Repository
- kajisho5/ffmpeg-skill4.3k
- Category
- Engineering
- Updated
- 4d ago
- License
- MIT
- Context cost
- Mediumabout 2,676 tokens
- Runs scripts
- No, instructions only
What it does
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, building the interpreter/toolchain environment the runner builds, 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.
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.
# 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:
- The commands and their order.
- The paths each command is scoped to (
ruff check app tests scriptsis notruff check .). - Test selection, marker expressions,
-kfilters, which suites are excluded. - The
env:block, and the runtime/toolchain versions insetup-*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.
Markers. A suite-wide make test that excludes one marker is not the CI
gate if CI excludes six. Live-credential integration tests deselected in CI will
run locally, hit a fake key, and fail in a way that looks like a regression:
# Wrong: local shorthand, pulls in suites CI never runs
pytest -m "not browser"
# Right: the full expression, copied from the workflow
pytest -m "not browser and not slow and not load and not integration"
