Continuous Integration
Developers integrate code into a shared repository frequently — usually multiple times per day — with automated build and test verification.
What it is
Continuous Integration (CI) is the practice of merging all developer working copies to a shared main branch several times a day. Each integration is verified by an automated build and automated tests, giving the team immediate feedback on whether the change broke anything. The goal is simple: the main branch should always be in a working state.
When a developer commits, the CI server checks out the code, compiles it, runs the test suite, and reports the result. If the build fails, the team stops and fixes it before doing anything else. This discipline prevents the integration hell that occurs when multiple long-lived branches are merged at the end of a sprint, each containing weeks of conflicting changes.
The CI mantra: Commit to main daily. If the build is red, fixing it is the highest priority work in the team.
When to use it
Every code commit, multiple times per day. CI is not a scheduled activity like a nightly build; it is a continuous, automatic response to every push. Teams practising CI should be integrating at least once per developer per day, and often far more frequently.
CI is foundational for teams that also practise Continuous Delivery or Deployment, because you cannot safely deploy code that has not been continuously integrated and tested.
Key benefits: faster bug detection, reduced merge conflicts, immediate feedback on quality, living documentation through test results, and a main branch that is always deployable.
Key concepts
The Integration Problem
When developers work on isolated branches for days or weeks, they diverge from each other and from main. The longer the isolation, the harder and riskier the merge. CI solves this by forcing small, frequent integrations so conflicts remain small and manageable.
The Build Pipeline
A CI pipeline is a sequence of automated stages: compile, unit test, integration test, static analysis, package. Each stage must pass before the next begins. Pipelines are defined as code (YAML in GitHub Actions, GitLab CI, Azure Pipelines, or Jenkinsfile) so they are version-controlled and repeatable.
Fix or Revert
If a commit breaks the build, the author has two choices: fix it immediately, or revert the commit to restore main to green. There is no third option of leaving it red while finishing another task. A red main is a blocked team.
Pre-commit Checks
Fast feedback is better when it happens before the push. Pre-commit hooks run linters, formatters, and fast unit tests locally so the developer catches issues before CI even sees them. They should be quick (under a minute) or developers will skip them.
| Stage | Purpose | Typical Duration |
|---|---|---|
| Compile / Build | Ensure code is syntactically valid and dependencies resolve | 1–3 minutes |
| Unit Tests | Verify individual components in isolation | 2–5 minutes |
| Integration Tests | Verify components work together with real or test doubles | 5–15 minutes |
| Static Analysis | Catch code smells, security issues, and style violations | 1–3 minutes |
Common pitfalls
- Long-running feature branches. A branch that lives for a week is not CI. If you must use branches, keep them under a day and merge to main constantly.
- Ignoring broken builds. A red build that sits for hours trains the team to ignore CI. Fix it or revert it immediately.
- Slow builds. If the pipeline takes 45 minutes, developers will batch commits and context-switch while waiting. Aim for under 10 minutes for the feedback that matters most.
- Insufficient test coverage. CI without meaningful tests is just automated compilation. You need tests that can actually catch regressions.
- Committing without local tests. Pushing code you have not run locally is rude to your team. Run the relevant tests before pushing, every time.
Red flag: If your team has a “code freeze” before release because main is unstable, your CI practice has broken down. The freeze is a symptom; the cure is smaller commits and stronger tests.
NZ context
Government digital teams in New Zealand, including those under the Digital Service Design Standard, require Continuous Integration as a baseline capability. Teams working with agencies such as ACC, Inland Revenue, or Ministry of Social Development must demonstrate that their main branch is automatically built and tested on every commit.
Smaller NZ consultancies and startups often run CI on cloud-hosted runners (GitHub Actions, GitLab CI) rather than maintaining their own infrastructure. This keeps costs predictable and scales with team size. For teams handling sensitive data, self-hosted runners within New Zealand cloud regions meet data residency expectations while retaining automation benefits.
Career level guidance
| Level | Focus | Milestones |
|---|---|---|
| Junior | Commit to main daily; run tests locally before pushing; read build logs | Understands pipeline stages; can diagnose and fix their own build failures; writes tests that run in CI |
| Senior | Design pipeline architecture; optimise build times; enforce fix-or-revert discipline | Reduces build time by 50% or more; sets up parallel test execution; coaches team on CI hygiene |
| Test Lead | Define quality gates; measure pipeline health; integrate security and compliance checks | Tracks build pass rate and mean time to recovery; implements mandatory pre-commit checks; audits pipeline for coverage gaps |
Tip for test leads: Publish a dashboard showing build pass rate, average build duration, and mean time to recovery (MTTR) after a red build. What gets measured gets improved.