Production Hygiene: CI Gates
Goal: you can wire the house loop into GitHub Actions so nothing merges unless fmt, clippy, and tests pass — and know the release checklist by heart.
The CI file (our actual pattern)
name: CI
on:
pull_request: { branches: [develop, main] }
push: { branches: [main] }
jobs:
check: { runs-on: ubuntu-latest, steps: [ { uses: actions/checkout@v4 },
{ uses: dtolnay/rust-toolchain@stable },
{ uses: Swatinem/rust-cache@v2 },
{ run: cargo check --all-targets } ] }
format: { runs-on: ubuntu-latest, steps: [ { uses: actions/checkout@v4 },
{ uses: dtolnay/rust-toolchain@stable },
{ run: cargo fmt --all -- --check } ] }
clippy: { runs-on: ubuntu-latest, steps: [ { uses: actions/checkout@v4 },
{ uses: dtolnay/rust-toolchain@stable },
{ uses: Swatinem/rust-cache@v2 },
{ run: cargo clippy --all-targets -- -D warnings } ] }
test: { runs-on: ubuntu-latest, steps: [ { uses: actions/checkout@v4 },
{ uses: dtolnay/rust-toolchain@stable },
{ uses: Swatinem/rust-cache@v2 },
{ run: cargo test --workspace } ] }
(Condensed for reading — real repos list the steps in full YAML; the jobs and the
commands are exactly these. Swatinem/rust-cache is what keeps the re-runs fast.)
Why five separate jobs
Check/Format/Clippy/Test/Build run in parallel and report separately — a format failure doesn’t hide behind a 40-minute test queue, and the red X tells you which gate broke. Required-checks settings then refuse merges unless all five are green.
Release checklist (uteke/Sinau pattern, memorize)
CHANGELOG.mdupdated — every user-visible change, since v0.0.1- Docs in sync (README,
.env.example) - PR
develop → mainvia PR, never direct push - All 5 required checks green on the PR
- Cora review/scan before declaring done
- Tag
v0.x.yafter merge — 0.x.x forever: minor = feature, patch = fix - Push tag; CI artifacts/release from the tag
Local discipline that makes CI boring
cargo fmtbefore every commit (rustfmt may reformat files you didn’t touch — let it)- New route/module in a binary crate? Register it in both the real router and the test router — a missed registration is a 404 that only shows up in tests
- Every fix ships with the test that would have caught it
Done when: you can reproduce this CI file from memory (jobs + commands), and you can recite the release checklist without looking — that is the bar for “knows how we ship”.