Skip to content
Français
Account: not signed in, sync available My learning
Select theme
Français
Lire en français

CI, Continuous Delivery, Continuous Deployment: which level to choose?

By updated

Improve this page

Continuous integration validates every change, continuous delivery keeps the code deployable at any time, continuous deployment puts it in production with no human intervention. The last two share the "CD" acronym, hence the confusion. Choosing the level is not a matter of vocabulary: it shapes the team's culture, its testing requirements and the risk it accepts. This lesson defines the three practices, helps you choose your level and shows a complete chain that links them.

What you will learn

  • Tell continuous integration, continuous delivery and continuous deployment apart
  • Apply the four rules that make CI effective
  • Justify a human approval before production
  • Check the prerequisites of continuous deployment before adopting it
  • Read a complete chain and locate its approval gate
  • Recognise the trap of premature "full CD"

The three levels of automation

Each level includes the previous one: no continuous delivery without continuous integration, no continuous deployment without continuous delivery. It is a progression, not a choice between three equivalent options. The diagram shows where each one stops: CI stops at validation, delivery at a ready artifact, deployment at production.

The three levels as a progression: CI builds and tests to give developers feedback (mandatory), continuous delivery makes code ready to ship with a human approval (recommended), continuous deployment deploys automatically with no human step (optional).CI: build + test, dev feedbackmandatory for every teamCD (Delivery): ready to shiphuman approval, recommendedCD (Deployment): deployed automaticallyno human step, optional
Source · SVG
Esc to close, + and − to zoom, scroll to move around. 100 %

Continuous integration, the mandatory foundation

Continuous integration (CI) validates every change as soon as it is pushed, before it joins the main branch. Picture five developers, each on their own branch: Alice pushes on Monday, Bob on Tuesday, each piece of code compiles on its author's machine, and on Friday the merge no longer compiles, because the two changes are incompatible without anyone knowing.

With CI, the problem shows up immediately: as soon as Alice pushes, the pipeline checks that her code works with the rest, and she knows within minutes rather than five days. On every commit or pull request, the pipeline compiles, runs the unit and integration tests, static analysis and a scan for vulnerable dependencies.

Why CI is not negotiable

The later a bug is found, the more it costs: at commit time, its author still has the context in mind; in production, you have to find the faulty change, fix it under pressure and redeploy. CI brings detection as close as possible to the writing of the code.

The cost of fixing a bug grows over time: low at commit, higher at merge and then in staging, highest in production.the cost of a fixgrows over timeCommitlow costMergeStagingProdhighest cost
Source · SVG
Esc to close, + and − to zoom, scroll to move around. 100 %

The four rules of effective CI

CI only protects if it is respected. Every commit triggers it, without exception; a failure blocks the merge, so that no broken code reaches the main branch; tests stay fast, ideally under ten minutes, otherwise developers bypass the system; and feedback goes straight to the developer, in their interface or messaging tool.

Continuous delivery: ready to deploy, on decision

Continuous delivery extends CI: the code is not only validated, it is ready to go to production at any time. A human decides when. After CI, the pipeline builds an immutable artifact (image, binary, package), deploys it to staging, runs end-to-end tests on complete journeys, then waits for an approval.

Continuous delivery: CI, artifact build and staging deployment are automatic; going to production waits for a human to answer “Yes, go.” to the question “Do we deploy?”.“Yes, go.”CIautomaticBuild artifactautomaticStaging deployautomatic“Do we deploy?”manualProduction
Source · SVG
Esc to close, + and − to zoom, scroll to move around. 100 %

Why keep a human approval?

Human approval is not an admission of weakness: it is rational in four situations. A feature must ship together with a commercial announcement, and automatic deployment does not read the marketing calendar. A regulated sector (health, finance, aerospace) requires every production release to be documented and approved. The team does not yet have enough tests to do without it. Or the deployment affects partners who must be warned.

The key point fits in one sentence: with continuous delivery, the code is always deployable. The question is no longer "can we deploy?" but "do we want to deploy now?". It is this permanent availability that counts, not the absence of a button.

Continuous deployment: no human intervention

Continuous deployment removes the last barrier: every validated change goes automatically to production. A developer merges their pull request at 2:03 pm; at 2:08 pm, the code serves real users, without anyone clicking "deploy". As early as 2011, Amazon announced a production deployment every 11.6 seconds on average.

Continuous deployment: CI, artifact build, staging and then production deployment run automatically, with no human between the commit and production.autoautoautoCIBuildartifactStagingdeployProductiondeployNo humanbetween commit and prod
Source · SVG
Esc to close, + and − to zoom, scroll to move around. 100 %

The prerequisites, and they are strict

With no human in the loop, a bug that passes the tests reaches production. Continuous deployment therefore requires five foundations. Tests covering every critical path. Feature flags, which ship disabled code and let you switch a feature off without redeploying. An automatic rollback when error rates or latency degrade.

It also takes observability that detects a problem within seconds, with alerts, dashboards and centralised logs: you cannot fix what you cannot see. And a blameless culture, where an incident serves to improve the system rather than to point at a culprit, otherwise developers will be afraid to merge. The teams that work this way have invested years in it: it is a destination, not a starting point.

Side-by-side comparison

The table sets the three practices against eight criteria. Read the "production deployment" and "human intervention" rows above all: that is where the difference between the two CDs lies. The other rows show what each level adds in requirements, especially in testing and rollback.

AspectCIContinuous deliveryContinuous deployment
TriggerCommit, pull requestMerge into mainMerge into main
Artifact producedOptionalMandatoryMandatory
Staging deploymentOptionalMandatoryMandatory
Production deploymentNoManualAutomatic
RollbackNot applicableManualAutomatic
Testing requirementUnitEnd-to-endEnd-to-end and canary
Time to productionNot applicableHours to daysMinutes
Human interventionNoneFinal approvalNone

How do you choose your level of automation?

The right level is the one the team can sustain, and it is climbed in order. Start with CI if it is missing: it is the top priority, with a clear minimum goal, every pull request triggering a pipeline, tests that block the merge on failure and feedback in under ten minutes. The rest can wait until this foundation is in place.

Once CI is stable, move to continuous delivery: immutable artifacts, automatic deployment to staging after each merge, end-to-end tests, human approval before production. It is the sufficient level for most teams, and human approval is often the right answer there, not a failure.

Continuous deployment is considered next, and only if four answers are "yes": are the critical paths covered by automated tests? Is a production problem detected within a few minutes? Is rollback automatic? Does the team handle incidents without looking for a culprit? A single "no", and continuous delivery remains the right choice.

What does a complete chain look like, from CI to production?

A continuous delivery chain links the three levels in a single file: the CI part validates every change, the CD part deploys to staging then to production, and an approval gate separates the last two steps. The file below is written for GitHub Actions: it reads without knowing the syntax, which the GitHub Actions course teaches, and it illustrates what the lessons of the course build step by step.

The CI jobs (lint, test, security) run in parallel, then build only starts if all three succeed, thanks to the needs key. The CD part follows the same chaining up to production. The image is built only once, tagged with the commit SHA, and that is the image the environments receive.

name: CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
# No permission by default: each job only receives what it needs
permissions: {}
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
# ===== CONTINUOUS INTEGRATION =====
lint:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run lint
test:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run test -- --coverage
- uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
security:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Run Trivy
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0, pinned by SHA
with:
scan-type: 'fs'
severity: 'CRITICAL,HIGH'
- name: Check secrets
uses: gitleaks/gitleaks-action@e0c47f4f8be36e29cdc102c57e68cb5cbf0e8d1e # v3.0.0
build:
needs: [lint, test, security]
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
- uses: docker/login-action@06fb636fac595d6fb4b28a5dfcb21a6f5091859c # v4.5.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
# ===== CONTINUOUS DELIVERY =====
deploy-staging:
if: github.ref == 'refs/heads/main'
needs: build
runs-on: ubuntu-latest
environment: staging
steps:
- name: Deploy to staging
run: |
echo "Deploying to staging..."
# kubectl, ArgoCD, or another deployment tool
integration-tests:
needs: deploy-staging
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Run E2E tests on staging
run: npm run test:e2e
env:
BASE_URL: https://recette.inventaire.lab
deploy-production:
needs: integration-tests
runs-on: ubuntu-latest
environment:
name: production
url: https://inventaire.lab
steps:
- name: Deploy to production
run: |
echo "Deploying to production..."
# Deployment with a Blue/Green or Canary strategy

Two security settings frame this file: permissions: {} removes every default right from the GitHub token, each job receiving only the strict minimum (packages: write to publish the image), and persist-credentials: false keeps the token from staying on the runner's disk after the checkout. The Deploy steps only run an echo: the real deployment depends on the target.

The environment: production key is what makes this file continuous delivery rather than continuous deployment. On GitHub, it triggers a configurable protection rule: manual approval, branch restriction or wait timer. Remove the rule, and the same file goes to production with no intervention: the level of automation is tuned without duplicating the pipeline.

The "full CD" trap

Some teams want to "do continuous deployment" to tick a box or because a big company does it, without having the prerequisites. The result is predictable: bugs in production every day, developers who are afraid to merge and therefore merge less often, manual rollbacks in a hurry, then a loss of confidence in the pipeline.

Continuous deployment is not a goal in itself, it is the consequence of an acquired maturity. The right approach is to stay with continuous delivery and strengthen tests, observability and culture. The day human approval no longer adds anything, because the tests catch what it would have seen, moving to continuous deployment becomes natural.

Key points

  • CI validates every commit automatically: it is mandatory for every team.
  • Continuous delivery keeps the code always deployable, the production release remaining a human decision.
  • Continuous deployment releases to production without human intervention, and requires tests, feature flags, automatic rollback, observability and a blameless culture.
  • Each level includes the previous ones: there is no shortcut.
  • A human approval is often the right answer, not a failure.
  • Premature "full CD" creates more problems than it solves.

Knowledge check

Check that the essentials of this lesson are in place. The questions only cover what has just been explained here.

Knowledge check

Check what you have learned with this interactive quiz

6 questions
6 min
70% to pass

How it works

  • The timer starts when you click Start
  • Multiple choice, true/false and short answer questions
  • You can move between questions
  • Detailed results are shown at the end

Starts the quiz and the timer

Is this project useful to you?

The guides, courses, quizzes and labs stay free. If you use them regularly, you can contribute to their upkeep and development.

Become a supporting member (new tab) One-time support (new tab) Learn more

Follow the project on LinkedIn