# Reproducing Ci Locally

Run the CI gate on your machine so it agrees with the runner, deriving the exact...

- Repository: https://github.com/kajisho5/ffmpeg-skill (4279 stars)
- Category: Engineering
- License: MIT
- Last updated: 2026-10-31
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add kajisho5/ffmpeg-skill --skill reproducing-ci-locally -g -a claude-code -y`
Codex: `npx skills add kajisho5/ffmpeg-skill --skill reproducing-ci-locally -g -a codex -y`
Cursor: `npx skills add kajisho5/ffmpeg-skill --skill reproducing-ci-locally -g -a cursor -y`
Gemini CLI: `npx skills add kajisho5/ffmpeg-skill --skill reproducing-ci-locally -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add kajisho5/ffmpeg-skill`

## Description

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.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# 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.

**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:

```bash
# 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"
```

The rest: https://github.com/kajisho5/ffmpeg-skill/blob/HEAD/.claude/skills/reproducing-ci-locally/SKILL.md
