| Continuous Integration | Continuous Delivery | Continuous Deployment | |
|---|---|---|---|
| Scope | Plan → Test | up to Release | up to production Deploy |
| Each commit | Automatic build + test on a shared branch | Becomes a release-ready artifact, deployed to staging | Reaches production if every check passes |
| Step to production | — | Human approval (a button) | Automatic, no approver |
| Prerequisites | Small, frequent commits to main |
Reliable pipeline, matching environments | Excellent automated tests, feature flags, fast rollback |
flowchart LR
C["Commit"] --> B["Build"] --> T["Test"] --> S["Deploy staging"] --> G{"Approve?"}
G -- "Continuous Delivery: a person clicks" --> P["Production"]
G -. "Continuous Deployment: automatic" .-> P
- CI: integrate code into a shared branch several times a day; each time it is built and tested so bugs surface early. CI does not include production deployment.
- Quality gate: a condition that stops the pipeline (failed tests, low coverage, critical vulnerabilities).
- The wider the scope, the greater the business value; DevOps also covers Operate and Monitor, built on collaboration.
- Supporting practices: automation checklists, continuous improvement, preventing defects early.
DORA metrics measure delivery performance:
| Metric | Question |
|---|---|
| Deployment frequency | How often do you deploy to production? |
| Lead time for changes | How long from commit to production? |
| Change failure rate | What % of deployments cause an incident? |
| Time to restore service | How long to recover from an incident? |
Trap: mixing up the two "CD"s — Delivery has a manual approval step, Deployment does not.
| Command | Meaning |
|---|---|
git log --oneline main..feature/login |
Commits on feature/login not yet integrated into main |
Anatomy of a pipeline
commit → build → unit tests → static analysis → package (image/artifact)
→ deploy to test → integration tests → approval → deploy to production
| Building block | Meaning |
|---|---|
| Trigger | What starts a run: a push, a pull request, a schedule, a manual button |
| Stage / job / step | Groups of work; jobs can run in parallel on different agents |
| Agent / runner | The machine or container that executes the steps |
| Artifact | The output passed between stages: a JAR, a ZIP, a container image |
| Environment | A deployment target such as dev, staging, prod, often with its own approvals and secrets |
Principles that make CI/CD work
- Build once, deploy many: produce one versioned artifact and promote the same one through every environment, instead of rebuilding for each.
- Keep the pipeline fast: aim for feedback within about ten minutes so developers wait for it instead of ignoring it. Run quick checks first and slow tests later or in parallel.
- Fix a red build first: a broken
mainblocks everyone; whoever broke it reverts or fixes it immediately. - Pipeline as code: define the pipeline in a file in the repository (
Jenkinsfile,azure-pipelines.yml,.github/workflows/*.yml) so it is reviewed and versioned like the application. - Trunk-based development: short-lived branches merged to
mainat least daily keep integration painless; long-lived branches cause big, risky merges.
Shift left
Testing and security checks moved earlier ("left") in the pipeline find problems when they are cheap to fix: linting and unit tests on every commit, dependency and container scanning before an image is published, infrastructure checks before terraform apply.
Popular tools
Jenkins, GitHub Actions, GitLab CI/CD, Azure Pipelines, CircleCI, and cloud-native options such as AWS CodePipeline all implement the same ideas with different syntax. The concepts in this module carry over between them; the Jenkins and Azure DevOps modules show two in detail.