BitBootcampBitBootcamp ← all explainers 🔄 Review ⚙ Settings

DEVOPS-03-001-P · Primer — CI, CD, and Continuous Deployment

The idea in one sentence

Three practices hide behind the letters "CI/CD," and they are not the same promise: continuous integration means everyone merges their work often and an automated build proves it still fits together, continuous delivery means the software is kept in a state where you could ship any green build to production at any moment, and continuous deployment means every green build does ship to production automatically, with no human pressing the button.

Why it exists

Rewind to how teams worked before any of this. Five developers each take a feature, disappear onto their own branch for two weeks, and code in isolation. On Friday everyone tries to merge. Now the pain arrives all at once: Alice changed a function signature that Bob's code calls, Carol renamed a file three people import, and the tests that passed on each laptop fail together. This is integration hell — the longer people work apart, the more their changes diverge, and the merge at the end is a bruising, unpredictable slog nobody can estimate.

Then, even after the merge finally builds, there's a second wall: getting it to real users. Release day is a hand-cranked ritual — someone copies files to a server at midnight, runs steps from a checklist in a wiki, and prays. Because it's scary and manual, releases get batched up and done rarely, which makes each one huge, which makes it scarier. A vicious loop: releasing is risky, so we release less, so each release carries more change, so it's riskier still.

The three C's exist to break both walls. Continuous integration attacks the first: merge small changes constantly and prove each merge with automation, so integration is a tiny daily non-event instead of a Friday catastrophe. Continuous delivery attacks the second: make releasing a boring, automated, always-ready capability so you can ship on demand. Continuous deployment goes one step further and removes the last manual gate entirely. People blur them into one buzzword, but each solves a distinct problem, and knowing which one you actually have — or want — is the whole point.

How it works

Think of a pipeline: an automated assembly line that a code change travels down. Each C owns a different stretch of it.

Continuous integration — merge often, prove it builds. Every developer integrates their work into the shared mainline frequently — Fowler's benchmark is at least daily, and many teams merge many times a day. Each integration triggers an automated build and an automated test suite. The rule that makes CI real: keep the mainline green (building and passing) at all times, and if a merge turns it red, fixing that is the team's top priority before anything else moves. Because each change is small and integrated immediately, conflicts surface in minutes while they're trivial, not in a two-week pile-up. CI's deliverable is a validated artifact — a build that has demonstrably passed its checks. Note what CI does not promise: it says nothing about shipping. A perfectly green CI pipeline can still leave you deploying by hand at midnight.

Continuous delivery — keep it always-releasable. CD extends the pipeline past "it builds" to "we could ship this." After CI produces a validated artifact, further automated stages deploy it to production-like environments and run broader checks — integration tests, acceptance tests, sometimes performance and security gates. The goal, in Jez Humble's framing, is the ability to get changes of all types into the hands of users safely, quickly, and sustainably. The defining property: the software is always in a deployable state, so a release is a business decision, not an engineering scramble. Crucially, continuous delivery does not mean you deploy on every change — it means the final push to production is a one-click, on-demand action a human chooses to take. The button exists; a person still presses it.

Continuous deployment — ship every green build. This is the one-word difference that trips everyone up. Continuous deployment removes that final human gate: every change that passes the entire automated pipeline is deployed to production automatically, no approval, no button. Merge, go green, and minutes later it's live for users. That is the only distinction between continuous delivery and continuous deployment — not the tooling, not the tests, just whether a human still approves the last step. Delivery = automated up to a human's on-demand click. Deployment = automated all the way to production.

Two clarifications that save confusion:

The one gotcha

The gotcha is believing "we have a CI tool, so we do CI/CD" — the practices are disciplines, not products, and the pipeline is only as honest as the tests it runs. Installing Jenkins or GitHub Actions gives you automation; it does not give you continuous integration. If developers still sit on long-lived branches for a week, you have a build server, not CI — you've automated the build but not the integrating often that is the entire point. And the deeper trap sits underneath continuous deployment: the moment there is no human checking the release, the automated test suite is the only thing standing between a bad commit and your users. A gap in your tests is now a direct, unattended path to a production outage. This is why you earn continuous deployment rather than switch it on — it demands genuinely trustworthy tests, fast rollback, and usually feature flags and health-checked, gradual rollouts, so a mistake is caught and reverted in minutes instead of quietly breaking everyone. Automating the deploy of a suite you don't trust doesn't speed you up; it just ships your bugs faster.

See it — the same pipeline, where each C stops

flowchart TB
    DEV["Developer merges<br/>small change to mainline"]
    BUILD["Automated build<br/>+ automated tests"]
    ART["Green validated<br/>artifact"]
    STAGE["Deploy to prod-like env,<br/>broader checks"]
    READY["Always in a<br/>deployable state"]
    GATE{"Who releases<br/>to production?"}
    HUMAN["Human clicks<br/>on demand"]
    AUTO["Pipeline deploys<br/>automatically"]
    PROD["Live for users"]

    DEV --> BUILD --> ART
    ART -->|"CI stops here"| STAGE
    STAGE --> READY
    READY -->|"CD: delivery stops here"| GATE
    GATE -->|"continuous delivery"| HUMAN --> PROD
    GATE -->|"continuous deployment"| AUTO --> PROD

The one-line takeaway

Integrate often and keep the build green (CI); keep every green build shippable on demand (continuous delivery); ship every green build with no human in the loop (continuous deployment) — three escalating promises, not three words for the same thing.

Where you'll meet it

You'll meet the CI half the first time a pull request won't merge until a green checkmark appears — that checkmark is your build-and-test pipeline enforcing "keep the mainline green." You'll meet the CD distinction the day you ship: if a teammate clicks "Deploy to production" after the pipeline passes, that's continuous delivery; if merging to main quietly puts code live for users with nobody approving it, that's continuous deployment. Interviewers love this exact question — "what's the difference between continuous delivery and continuous deployment?" — because the sloppy answer treats them as synonyms and the strong answer nails the single difference: whether a human still presses the button. The best answers go further and note why continuous deployment is the higher bar — it makes your test suite and rollback story the last line of defense — and mention the guardrails that make it safe: reliable automated tests, feature flags, gradual health-checked rollouts, and fast rollback. Name the stack too: continuous deployment sits on continuous delivery, which sits on continuous integration. You earn each layer before the next.

Named concepts: continuous integration, continuous delivery, continuous deployment