pre-ci
Skill548 starsChanged 10 days agoApache-2.0View on GitHub
Run all locally-executable CI checks (format, lint, unit tests) for the areas you changed
In this repository54 other files it gives its agents.
- AGENTS.mdAGENTS.md
- backend/AGENTS.mdAGENTS.md
- docs/AGENTS.mdAGENTS.md
- backend/CLAUDE.mdCLAUDE.md
- CLAUDE.mdCLAUDE.md
- docs/CLAUDE.mdCLAUDE.md
- analyzing-ci-flakinessSkill
- audit-docsSkill
- commitSkill
- creating-changelog-entriesSkill
- creating-issuesSkill
- creating-prdSkill
- grilling-ideasSkill
- harvesting-reviewSkill
- migrate-feature-pageSkill
- monitoring-pull-requestsSkill
- neo4j-cypher-guideSkill
- opsmill-dev-analyzing-bugsSkill
- opsmill-dev-fixing-bugsSkill
- opsmill-dev-test-driving-bugsSkill
- prSkill
- rebaseSkill
- reviewing-pull-requestsSkill
- speckit-agent-context-updateSkill
- speckit-analyzeSkill
- speckit-checklistSkill
- speckit-clarifySkill
- speckit-constitutionSkill
- speckit-convergeSkill
- speckit-critique-runSkill
- speckit-git-commitSkill
- speckit-git-featureSkill
- speckit-git-initializeSkill
- speckit-git-remoteSkill
- speckit-git-validateSkill
- speckit-implementSkill
- speckit-opsmill-autoSkill
- speckit-opsmill-extractSkill
- speckit-opsmill-implementSkill
- speckit-opsmill-prepSkill
- speckit-opsmill-retrospectSkill
- speckit-opsmill-summarySkill
- speckit-planSkill
- speckit-review-codeSkill
- speckit-review-commentsSkill
- speckit-review-errorsSkill
- speckit-review-runSkill
- speckit-review-simplifySkill
- speckit-review-testsSkill
- speckit-review-typesSkill
- speckit-specifySkill
- speckit-tasksSkill
- speckit-taskstoissuesSkill
- upgrading-infrastructure-dependenciesSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 2 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 28
Run the locally-executable CI checks that apply to what you changed.
- Distinctive: line 54
Run only the phases for the areas that changed, plus those marked always-run.
- Distinctive: line 227
Run after all lint and validation checks pass.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Pre-CI
Run the locally-executable CI checks that apply to what you changed. Every check below mirrors
a job in .github/workflows/ci.yml — keep them in parity.
Every command runs from the repository root and must leave the working directory unchanged.
The parallel phases share a single shell, so a cd in one command changes where its siblings run
and the invoke tasks then fail on relative paths. Use pnpm --dir for the frontend checks —
never cd frontend/app && ....
Options:
--fast— Formatting and fast lint only (~20s). Skips mypy, Betterer, docs lint, generated-file and doc validation, schema validation, and all unit tests.--all— Skip detection and run every phase regardless of what changed.
Phase 0 — Detect what changed
Identify which areas below this branch touched — committed, staged, and untracked — relative to
its base: stable, develop, a release-* branch, whichever long-lived branch it forked from.
git fetch the candidates first so the base is not stale, then collect paths from three places:
git diff --name-only --no-renames <merge-base>...HEAD for committed work, the same command
against HEAD for staged and unstaged work, and git ls-files --others --exclude-standard for
untracked files. Keep --no-renames: without it a rename reports only the new path, so the area
that lost the file is never flagged.
Run only the phases for the areas that changed, plus those marked always-run. When unsure about the base, or whether a path counts, include it. Over-running is cheap; a missed area is a red PR.
Classify the paths using the globs from .github/file-filters.yml, so local gating matches the
files-changed outputs CI branches on. Two rows are intentional exceptions — do not "correct"
them: python is narrowed to keep the slow phases off models/ and root-script changes, and
schema is local-only, since backend_all has no schema/** entry for it to mirror.
| Area | Paths | Enables |
| frontend | frontend/app/**, frontend/packages/**, frontend/package.json, frontend/pnpm-workspace.yaml, frontend/pnpm-lock.yaml, schema/openapi.json, frontend/app/src/shared/api/rest/types.generated.ts, development/**, tasks/**, .github/workflows/ci.yml, .github/file-filters.yml | Phases 1A, 3B |
| backend | backend/**, python_sdk, development/**, tasks/**, **/pyproject.toml, **/uv.lock, .github/workflows/ci.yml, .github/file-filters.yml | Phases 1B, 2B, 4B, 4C.2, 4D, 5.1 |
| python | any other **/*.py — models/, utilities/, python_testcontainers/, tests/, root scripts | Phases 1B, 2B, 4C.2 |
| testcontainers | python_testcontainers/**, .github/workflows/*.yml (any workflow, not just ci.yml) | Phase 5.2 |
| docs | docs/**, **/*.{md,mdx}, .vale/**, .vale.ini, package.json, package-lock.json, development/**, tasks/**, python_sdk | Phases 1C, 4C |
| schema | schema/** | Phase 4D |
| yaml | **/*.{yml,yaml}, **/pyproject.toml, **/uv.lock | Phase 2C |
Three frontend validation jobs gate on their own narrow filters rather than the whole frontend area — check these paths separately:
| Trigger paths | Enables |
schema/openapi.json, frontend/app/src/shared/api/rest/types.generated.ts | Phase 3C |
schema/schema.graphql, frontend/app/src/shared/api/graphql/generated/** | Phase 3D |
schema/error-catalogue.json, frontend/app/src/shared/api/errors/catalogue.generated.ts, frontend/app/scripts/generate-error-bindings.mjs | Phase 3E |
State the detected areas before running anything, e.g.
Detected changes: frontend, docs. Skipping backend phases.
Sub-step letters are stable per area — A frontend, B backend or python, C docs (yaml
in Phase 2), D schema — so a phase omits letters where an area has nothing to do. Phase 3 is
entirely frontend: 3A–3E enumerate its individual CI jobs.
Phase 3A always runs, even with no frontend changes. The
frontend-lintjob has no path filter — a backend-only change still fails CI if frontend lint is broken on your branch. Only the frontend tests (Phase 3B) are path-gated.
Phase 1 — Auto-fix formatting (sequential)
These modify files and must complete before any lint check.
1A. Frontend — if frontend changed
pnpm --dir frontend/app run biome:fix1B. Python — if backend or python changed
uv run invoke format1C. Documentation — if docs changed
uv run invoke docs.formatPhase 2 — Fast checks
Send all applicable commands in a SINGLE message as parallel Bash calls.
2B. Python — if backend or python changed
uv run invoke main.lintuv run ruff check . --exclude python_sdkuv run ruff format --check --diff --exclude python_sdk .uv run ty check .uv lock --check— root project (jobinfrahub-uv-check). On failure runuv lockand commit the updated lockfile.uv lock --check --directory python_testcontainers— same for the separatepython_testcontainersproject (jobinfrahub-testcontainers-uv-check).
Steps 2–4 are CI's python-lint job verbatim, and repo-wide — the invoke tasks are not.
2C. YAML — if yaml changed
uv run yamllint -s .— CI'syaml-lintjob. Call it directly, not viauv run invoke lint, which bundles unrelated steps.uv run invoke ci.validate-huge-runner-gate— theyaml-lintjob's second step. Every huge-runner job inci.ymlmust depend onhuge-runner-gate, and the gate on every GitHub-hosted job; this fails when a new job is not wired in.
If
--fastwas specified, stop here and report results, marking slow checks as "skipped".
Phase 3 — Frontend gate (CI parity)
The complete set of frontend checks CI runs. If dependencies are stale, first run
pnpm --dir frontend/app install --frozen-lockfile (CI always does).
3A. Lint trio — ALWAYS run, regardless of detected areas (job frontend-lint). Send as
parallel Bash calls:
pnpm --dir frontend/app exec biome ci .—biome ci, notbiome check --write: only thecivariant is check-only.pnpm --dir frontend/app run knip— unused exports, files, and dependencies.pnpm --dir frontend/app exec betterer ci—betterer ci, not barebetterer, which rewrites the snapshot instead of failing.
3B. Unit tests — if frontend changed (job frontend-tests). Sequential:
pnpm --dir frontend/app exec playwright install chromium— the suite runs in browser mode. One-off per machine; skip if already installed.pnpm --dir frontend/app run test:coverage— plainpnpm testskips coverage.pnpm --dir frontend/packages/graph run test— the@infrahub/graphsuite, a second step of the same job living outsidefrontend/app.
3C. OpenAPI types — if the OpenAPI trigger paths changed (job
frontend-validate-openapi-types). On a non-empty diff, stage and commit the regenerated file:
pnpm --dir frontend/app run codegen:openapi && git diff --exit-code frontend/app/src/shared/api/rest/types.generated.ts3D. GraphQL types — if the GraphQL trigger paths changed (job
frontend-validate-graphql-types). On a non-empty diff, commit both generated files:
pnpm --dir frontend/app run codegen:graphql && git diff --exit-code frontend/app/src/shared/api/graphql/generated/graphql-env.d.ts frontend/app/src/shared/api/graphql/generated/graphql-cache.d.ts3E. Error catalogue bindings — if the error-catalogue trigger paths changed (job
frontend-validate-error-catalogue). On failure, run
pnpm --dir frontend/app run generate:error-bindings and commit the result:
pnpm --dir frontend/app run check:error-bindingsPhase 4 — Slow backend and docs checks
Send all applicable commands in a SINGLE message as parallel Bash calls.
4B. Backend — if backend changed
uv run invoke backend.lint— call this task directly, notuv run invoke lint, which bundlesmain.lint,backend.lintandyamllint. mypy is what this phase adds over Phase 2.uv run invoke backend.validate-generated— on failure runuv run invoke backend.generateand report the regenerated files.
4C. Docs — if docs changed; step 2 also if any Python changed
uv run invoke docs.lint— markdownlint + vale, mirroringmarkdown-lintandvalidate-documentation-style. Pre-existing errors indocs/docs/may exist; only flag those in changed files. Does not cover thedocumentationjob, which runsuv run invoke docs.build— run that manually if you touched the Docusaurus config.uv run invoke docs.validate— reference docs generated from Python source (CLI, schema, events, repository config, config). On failure the correct files are already on disk; stage and commit them.
4D. Schema — if backend or schema changed
uv run invoke schema.validate-graphqlschema— regenerates, then checks for uncommitted diffs. On failure the correct file is already on disk; stage and commit it.uv run invoke schema.validate-jsonschema— same, forschema/openapi.json.
Phase 5 — Slow unit tests
Run after all lint and validation checks pass.
5.1 — if backend changed (job backend-tests-unit):
uv run invoke backend.test-unit5.2 — if testcontainers changed (job backend-testcontainers-unit):
uv run --directory python_testcontainers pytest --rootdir=. -c pyproject.toml -vs testsCI runs this as a Python 3.10–3.14 matrix; one interpreter is enough locally.
After all checks
Summarize in a table. Include every row; mark rows as skipped (no <area> changes) or
skipped (--fast) rather than omitting them.
| Check | CI job | Status |
Frontend format/lint (biome ci) | frontend-lint | ... |
Frontend unused exports (knip) | frontend-lint | ... |
Frontend TS regressions (betterer ci) | frontend-lint | ... |
Frontend unit tests (test:coverage) | frontend-tests | ... |
@infrahub/graph unit tests | frontend-tests | ... |
| OpenAPI types | frontend-validate-openapi-types | ... |
| Frontend GraphQL types | frontend-validate-graphql-types | ... |
| Error catalogue bindings | frontend-validate-error-catalogue | ... |
Python format (ruff format --check) | python-lint | ... |
| Main Python lint | python-lint | ... |
| Ruff (CI parity) | python-lint | ... |
| Lockfiles (root + testcontainers) | infrahub-uv-check, infrahub-testcontainers-uv-check | ... |
YAML lint (yamllint -s .) | yaml-lint | ... |
Type check (ty check .) | python-lint | ... |
| Backend lint (mypy) | backend-tests-integration, backend-tests-functional | ... |
| Generated files | backend-validate-generated | ... |
| GraphQL schema validation | graphql-schema | ... |
| JSON schema validation | json-schema | ... |
| Docs lint (markdownlint + vale) | markdown-lint, validate-documentation-style | ... |
| Generated docs validation | validate-generated-documentation | ... |
| Backend unit tests | backend-tests-unit | ... |
| Testcontainers unit tests | backend-testcontainers-unit | ... |
Then state one of:
- All applicable checks passed — safe to push. Name the areas that were skipped and why.
- Failed. List each failure with the exact command and suggested fix. Do not describe the branch as ready to push.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

