Tags: web-dev concept

Continuous Integration

Date: 2026-08-17


Merging everyone’s work into a shared branch frequently enough that conflicts stay small. It’s a practice, not a product — a team running GitHub Actions on three-week branches has bought the tool and skipped the practice.


Continuous integration (CI) is the discipline of integrating work into a shared mainline frequently — at least daily — with automated verification that the mainline still works.

The automation is in service of the practice. The practice is integrating often.

The problem it solves

WITHOUT
  4 developers, 3-week branches
    ↓
  each branch diverges
    ↓
  integration at the end
    ↓
  conflicts interact; someone's work
  is rewritten; two weeks of
  "integration phase"

WITH
  everyone merges daily
    ↓
  conflicts are small and immediate
    ↓
  integration stops being an event

Integration pain grows non-linearly with branch age — the conflicts don’t just accumulate, they interact — Branching Strategies.

What “continuous” requires

1  everyone merges to mainline
   at least daily

2  every merge triggers an automated
   build and test

3  the mainline is ALWAYS releasable

4  a broken build is fixed
   immediately, ahead of other work

Point 4 is the cultural one and the one that decides whether it works. A red build tolerated for a day means nobody trusts the signal, and everyone starts merging on top of broken code.

Point 3 is what makes incomplete work need feature flags — you can’t hold a feature back on a branch if branches don’t live long enough — Feature Flags.

The pipeline

push
  │ install         (cached)
  │ lint            fast, fails early
  │ typecheck       fast
  │ unit tests      fast
  │ build
  │ integration     slower
  │ e2e             slowest
  ▼
mergeable

Order by speed, not by importance. Cheap checks failing in twenty seconds beat waiting eight minutes to learn about a lint error — Pipeline Design.

Speed is the constraint

< 10 min    people wait for it
            ← the target

10–20 min   people context-switch
            → they lose the thread

> 20 min    people stop waiting
            → merge before it finishes
            → the gate is decorative

A slow pipeline is not a minor inconvenience — it changes behaviour. Once people stop waiting, CI has become a thing that occasionally emails you rather than a gate.

The levers, in order: caching, parallelism, running only affected tests, and moving the slowest checks off the blocking path — Build Caching.

Trust is the other constraint

FLAKY TESTS
  → re-run until green
  → a real failure gets re-run too
  → the gate is gone
  — Flaky Tests

TOLERATED RED MAIN
  → people merge on top of broken
  → the next failure is ambiguous

See: Flaky Tests

A pipeline people don’t trust is worse than none, because it costs time and provides no assurance. Quarantine flaky tests immediately rather than tolerating them.

What belongs in it

BLOCKING
  lint, format check
  type check — Type Checking in CI
  unit + integration tests
  build succeeds
  critical E2E journeys
  secret scanning — Secrets Management

NON-BLOCKING, REPORTED
  bundle size trend
  coverage trend
  full accessibility scan
  dependency audit
  visual diffs for review

See: Type Checking in CI · Secrets Management

The distinction matters. Everything blocking must be fast and deterministic; everything else informs without stopping work — and putting a slow non-deterministic check in the blocking set is how pipelines become untrusted.

CI is not CD

CI    integrate frequently, verify
      automatically
      → mainline always works

CD    deploy automatically once it does
      → Continuous Deployment

See: Continuous Deployment

CI is the prerequisite. Deploying automatically from a mainline nobody trusts is just shipping bugs faster.

Where teams get it wrong

  • Long branches with a CI badge. The tool without the practice
  • Running only on pull requests, not on the mainline. Then main can be broken by a merge and nobody knows — which also breaks bisect — Git Bisect
  • Tolerating red. The single most damaging habit here
  • No local equivalent. If developers can’t run the same checks before pushing, CI becomes the place mistakes are discovered — Pre-Commit Hooks
  • Skipping checks under deadline. Once, understandably. Twice, it’s the new normal