Software delivery · foundation
Continuous integration
Continuous integration is the practice of integrating small changes frequently and automatically building and testing each candidate revision in a clean, repeatable environment.
Why it matters
Fast, trustworthy feedback finds incompatibilities close to the change that introduced them and keeps the shared branch in a releasable, diagnosable state.
Mental model
How to reason about continuous integration
Every commit proposes a new shared baseline. The CI pipeline reconstructs that revision from declared inputs, runs ordered checks, and reports evidence before the proposal advances.
Analogy
An assembly line tests each newly attached component immediately, so a defect is traced to a small recent change instead of discovered after the whole machine is assembled.
Examples
See the boundary, not just the happy path
Worked example · Reproducible pipeline
checkout -> restore pinned dependencies -> lint -> test -> buildThe runner derives results from versioned configuration and locked inputs rather than undeclared state on a developer machine.
Worked example · Protect the shared branch
require the CI check before mergeBranch protection turns the pipeline from advisory feedback into an integration gate for known automated requirements.
Avoid · Normalize a flaky test
rerun the failed suite until it passesAutomatic retries can conceal nondeterminism and destroy trust. Quarantine with ownership and fix the underlying isolation, timing, or state leak.
Common mistakes
Misconceptions to remove early
Making the feedback loop too slow
Developers batch changes or ignore results when ordinary feedback takes too long. Parallelize independent checks, cache safely, and keep a fast required core.
Depending on runner snowflakes
Manual tools, mutable global state, or unpinned dependencies make failures irreproducible. Declare versions, isolate jobs, and build from a clean checkout.
Quick check
Can you predict the result?
1. What makes a CI result useful for a particular commit?
- • The pipeline reproducibly builds and tests that exact revision from declared inputs
- • The runner has accumulated many manual fixes
- • Tests are rerun until one attempt passes
2. Why are small, frequent integrations easier to diagnose?
Keep building