DevOps5 min read
CI/CD for a Monorepo: Getting GitHub Actions to Only Build What Changed
A monorepo CI pipeline that rebuilds everything on every commit doesn't scale past a handful of packages. Path filtering and caching fix it.
Tanjil Ahmed
Lead Software Engineer · Notionhive
A monorepo's biggest CI trap is treating it like a single project — every commit triggering every test suite, every build, regardless of what actually changed. It works fine at three packages and becomes a fifteen-minute tax on every commit at fifteen.
- Use path filters (`dorny/paths-filter` or Turborepo's own change detection) to only run jobs affected by the diff.
- Cache dependency installs and build outputs keyed on lockfile hash, not just branch name.
- Turborepo or Nx remote caching means a rebuild that already happened on another branch doesn't happen again.
- Split fast checks (lint, typecheck) from slow ones (e2e) so the fast feedback loop stays under two minutes.
The payoff isn't just developer patience — a fifteen-minute CI run gets skipped or force-merged around under deadline pressure, which defeats the entire point of having CI. A two-minute run gets waited for.
A CI pipeline people wait for prevents bugs. A CI pipeline people work around just delays them.
