A CI pipeline from zero: the smallest one worth having
Updated

The minimum useful pipeline: checkout, lint, test, build, and a gate that stops red from shipping.
Teams postpone CI until the project is big, then discover the project is big because nobody can verify changes. The smallest pipeline worth having fits on one screen and pays for itself in the first week: every push gets the same five checks, and red never ships.
The five stages
Checkout with pinned versions. The pipeline checks out an exact commit and uses pinned tool versions. Floating versions turn green builds into lottery tickets.
Lint and format check. Style arguments end here. The machine enforces the style, humans review the logic.
Unit tests with a time budget. Fast tests run on every push. The suite must finish in minutes; a 40 minute suite on every push trains everyone to ignore it.
Build the artifact. Produce exactly what would ship, then throw it away (deployment comes later). If the build step differs between CI and release, the checks verified fiction.
The gate. Red stops the merge. No exceptions for seniors, deadlines or demos. One exception teaches the team the gate is decorative.
Worked example: a fictional repo goes from zero to gated
The context below is fictional. Fictional repo ParcelAPI (fictional) has three contributors and zero automation; broken main happens monthly.
Day one: checkout plus lint plus the existing 40 tests, ten minute budget, gate on. First week: the gate catches two broken pushes before merge; each fix takes minutes instead of the usual broken-main morning. Day ten: build step added, producing the release archive; a version drift between two laptops is caught because CI pins the toolchain. Month two: narrow job permissions plus dependency cache cut runs from nine minutes to three, and nobody asks for exceptions anymore because the gate has never been wrong loudly.
Decision table: pipeline choices
| Choice | Pick | Why |
|---|---|---|
| Permissions | Narrowest per job | A compromised job reaches less |
| Cache | Dependencies only | Build outputs must be rebuilt to be trusted |
| Secrets | Only in jobs that need them | Every extra holder is a leak path |
| Red builds | Stop the line | A gate with exceptions is decoration |
Checklist: a pipeline worth trusting
- Same five checks on every push, no special cases.
- Tool versions pinned, not floating.
- No secret appears in any log.
- Red has stopped at least one merge (a gate never tested is a hope).
Related reading
- Build the gate hands on: Pipeline That Stops on Red.
- Then narrow it: Narrow Pipeline Permissions and Cache.
Straight answers
Frequently asked questions
What belongs in the first pipeline?
Checkout, lint, unit tests, build, and a stop gate. Deployment comes after the team trusts the gate.
How do I keep pipeline secrets safe?
Narrow permissions per job, secrets only where needed, and no secret ever printed in logs.
Cache or fresh every time?
Cache dependencies, never build outputs. A poisoned build cache is worse than a slow pipeline.