Module 1: From Your Machine To The Pipeline

7. CI vs CD: a first look

Description

By the end of this lesson you'll be able to clearly distinguish two acronyms that almost always appear glued together —CI/CD— and that people confuse all the time. You already know the first in depth: CI, Continuous Integration, is integrating and verifying —running the suite on every change to keep the main branch green—. The second, CD, is what comes after CI has gone green: delivering or deploying that already-verified code to the next place —a staging environment, or straight to production—. In one sentence: CI checks that the code is fine; CD takes it to where it needs to be. One verifies, the other sends. And the order matters: CD depends on CI, because there's no sense in automatically sending to production code you didn't verify.

You'll see why CD actually has two meanings worth not mixing —Continuous Delivery and Continuous Deployment—, how they differ, and why this guide teaches the CI of the tests in depth but only places CD without developing it. This is a deliberately brief lesson: its job isn't to teach you to deploy —that's another world, with other guides—, but to give you a clear map so you know where what this guide covers ends and where what it doesn't begins, without confusing the two halves of "CI/CD".

Connection to the module: this lesson closes the conceptual frame. Lesson 6 told you what CI protects —the green main branch—; this one shows you what happens with that green branch afterward: CD takes it and sends it. It's the boundary of the module and almost of the guide: from here on, everything that follows in the guide (modules 2 to 8) is about the CI of the tests —the first pipeline, the matrix, speed, coverage gates, flakies—; CD is named and placed, not taught. Lesson 8's mini-project stays, on purpose, on the CI side.

The factory and the delivery fleet

Think of it this way. A cookie factory has two very different halves. The first is production with quality control: dough is mixed, baked, and at the end of the line an inspector checks each batch —are they well baked?, are they the right size?—. If a batch passes inspection, it gets the "approved" stamp and goes to the warehouse. If not, it's stopped and doesn't leave the factory. That half guarantees that only good cookies reach the warehouse.

The second half is logistics and delivery: taking the already-approved cookies from the warehouse, loading them onto trucks, and taking them to the stores. This half doesn't check the cookie's quality —that already happened—; its job is to move the approved product from the warehouse to where the customer buys it. Logistics trusts the inspection's stamp: it delivers what was already approved, not what "might be fine".

CI is the first half: production with quality control. It runs the suite on every change and only lets code that passes into main —the green stamp of lesson 6—. CD is the second half: the logistics that takes that already-approved code and carries it to where it has to run —staging, production—. And notice the dependency, which is the key: the delivery fleet should only load cookies with a stamp. Delivering without prior inspection is sending stores batches that might be undercooked. That's why CD leans on CI: first you verify (CI), and only the verified is sent (CD). Teaching how to deliver before having quality control would be teaching how to distribute defects faster.

CI = verify: running the suite on every change so only working code gets through (the green branch). CD = send: taking that already-verified code and carrying it to the next place (staging or production). CD depends on CI —you don't send what you didn't verify—.

The two meanings of CD

Here's a subtlety that confuses a lot of people: CD means two different things depending on who you ask, and although they're related, they aren't the same. It's worth keeping them separate so as not to talk at cross purposes.

CD = Continuous Delivery. The pipeline, after verifying with CI, leaves the code ready to be deployed at any moment —packaged, approved, waiting in the warehouse—, but the last step, sending to production, is triggered by a human with a click. Continuous delivery automates almost the whole path, and leaves the final decision of "now, to production" in a person's hands. The cookie is on the truck with the engine running; someone gives the order to go.

CD = Continuous Deployment. It goes a step further: if CI goes green, the code is deployed to production automatically, without human intervention. There's no final click; the pipeline itself, after verifying, sends. The truck starts on its own as soon as the cookie gets the stamp. It's more automatic and more demanding: it requires enormous confidence in the test suite, because anything the tests don't catch goes straight to production without a human reviewing it.

The relationship between the three acronyms, on a ladder of automation:

AcronymWhat it automatesWho triggers the send to production
CI (Continuous Integration)Verify on every change— (doesn't deploy; only verifies)
CD = Continuous DeliveryVerify + leave ready to deployA human, with a click
CD = Continuous DeploymentVerify + deployNo one: automatic if CI goes green

Notice that the three share the same foundation: CI. Continuous delivery and deployment are extensions that add send steps after CI has verified. That's why "CI/CD" is written together: it's a continuum that always starts by verifying, and where CD decides how much of the path to production is automated. Without solid CI, neither form of CD is safe —you'd be automating the delivery of cookies without quality control—.

Why this guide teaches CI and only places CD

A bit of honesty about scope, in the guide's spirit. This guide is called "Testing in CI/CD", but its real and declared focus is the CI of the tests: setting up the pipeline that runs your suite on every change and protects the green branch. CD —deployment to production— is named so you know how to place it, but is not taught. There's an underlying reason for that boundary, and it's not laziness.

Deploying a real application is a world with its own problems, far from running a test suite: you have to package the app, manage servers or containers, handle databases and migrations, secrets and credentials, zero-downtime deployment strategies, rollback plans if something goes wrong, monitoring in production. None of that is testing, and putting it here would dilute the focus —which is running your tests well in CI—. Also, Reservo, our case, is pure logic with no app to deploy: there's no Reservo server to send to production, so there wouldn't even be anywhere to demonstrate CD honestly.

So the boundary is clear and on purpose: from here on, the guide goes deep into the CI of the tests —module 2 sets up the first pipeline, module 3 closes the environment gap, module 4 tests across several versions, module 5 speeds it up, module 6 puts coverage gates on it, module 7 handles flakies, and module 8 assembles Reservo's complete pipeline—. CD stays as what it is here: the next step, placed on the map, which other guides and other learning develop when you have a real app to deploy. Knowing it exists and where it fits is enough for this module; mastering it is another path.

Worked example: verify before sending

The dependency "CD leans on CI" isn't just a nice phrase: it's a concrete mechanism, and it's the same exit code from lesson 5. A CI/CD pipeline chains the verification and the send so that the send only happens if the verification exited with code 0. On the command line, that rule is written with &&: verify && send runs send only if verify finished well (exit 0). It's lesson 5's assembly line —fail fast— applied to the CI/CD boundary: if quality control doesn't give the stamp, logistics doesn't even start.

Let's simulate it with Reservo's suite as the verification stage (CI) and an echo as the symbolic "send" (CD). First, with the suite green:

$ python3 -m pytest && echo "CI green (exit 0): deployment PROCEEDS"
============================== 12 passed in 0.02s ==============================
CI green (exit 0): deployment PROCEEDS

What to expect. The suite passed (exit 0), so && lets the second command run: the "deployment" proceeds. The green stamp authorized delivery. Now, with a test red —the fragile one from lesson 2 in a clean environment—:

$ env -u RESERVO_PRO_DISCOUNT python3 -m pytest test_env_pricing.py && echo "deployment PROCEEDS"
============================== 1 failed in 0.03s ==============================
$ echo $?
1

The test failed (exit 1), and the second command —the deployment— never ran: the "PROCEEDS" message doesn't appear. The && cut the chain as soon as the verification exited with a non-zero code. That is, in miniature, the whole mechanism by which CD depends on CI: the send is chained behind the verification, and a red blocks it without anyone having to remember to block it. The raw cookie doesn't get on the truck because the truck only starts if the stamp arrived. In a real pipeline, that && is the relationship between the test stages and the deployment ones; the principle is identical to the one you already measured in lesson 5.

Common mistakes

Using "CI" and "CD" as if they were synonyms. What happens: someone says "we have CI/CD" to mean "we have a pipeline", without distinguishing whether that pipeline only verifies (CI) or also deploys (CD). When it comes time to talk concretely —"is this going to production on its own?"—, the confusion generates costly misunderstandings. Why it happens: the acronyms live glued together and people treat them as a single thing. How to spot it: if you couldn't say whether your pipeline deploys or only verifies, you're mixing the two. How to fix it: always ask yourself "does this pipeline verify or send?". Verifying on every change is CI; sending the verified to another place is CD. A pipeline can do only the first (very common and perfectly valid), or both.

Wanting continuous deployment without a solid suite. What happens: a team, excited, sets up automatic deployment to production (CD = continuous deployment) but with a poor test suite that covers little. The result is a machine that sends bugs to production faster, with no human to stop them. Why it happens: continuous deployment sounds modern and efficient, and it's easy to forget it rests entirely on the quality of the tests. How to spot it: if you're about to automate the send to production but wouldn't bet your salary that the suite catches the bugs, you're not ready. How to fix it: continuous deployment is the last step of a maturity, not the first. First a solid CI with a suite you really trust (everything this guide teaches); only then does it make sense to let the green go to production on its own. Continuous delivery (with a human on the final click) is a much safer intermediate point to start with.

Expecting this guide to teach deployment. What happens: someone arrives at "Testing in CI/CD" expecting to learn to send their app to production, and gets frustrated because the guide stays on the CI of the tests. Why it happens: the "D" in the title promises deployment. How to spot it: if you're looking in this guide for how to package and deploy your app, you're expecting something outside its boundary. How to fix it: adjust the expectation to what's declared —this guide makes you an expert in running your suite in CI, which is the foundation any CD leans on—. When you have a real app to deploy and solid CI underneath, deployment is a separate learning that builds on this base. Here you earn the foundation; the construction on top is another project.

Exercises

Exercise 1 — CI or CD? For each pipeline action, say whether it's CI (verify) or CD (send), and why in one sentence. (a) Running pytest on a PR's code. (b) Copying the approved app to the production servers. (c) Blocking a merge to main because a test failed. (d) Publishing a new version of the app in the app store after passing the tests. (e) Building the clean environment and installing dependencies to run the suite.

See solution
  • (a) CI. Running the suite on a change is the central act of verifying. Pure Continuous Integration.
  • (b) CD. Copying the app to production is sending already-approved code to its destination. Deployment.
  • (c) CI. Blocking the merge over a red test is protecting the green branch with the verification —lesson 6's turnstile—. CI.
  • (d) CD. Publishing the version in the store is sending the verified product to the place where the customer gets it. Deployment (probably triggered after a green CI).
  • (e) CI. Building the environment and installing dependencies are stages 1 and 2 of lesson 5's pipeline, in service of running the suite. Part of CI.

The lesson: the question that always classifies is "does this verify or send?". Verifying —running tests, blocking merges, preparing the environment to test— is CI. Sending —copying, publishing, deploying— is CD.

Exercise 2 — Delivery vs deployment. A team has a pipeline that: (1) runs the suite on every PR, (2) when merged to main, packages the app and leaves it ready in a warehouse, and (3) waits for a person to click "Deploy" to send it to production. (a) What part is CI and what part is CD? (b) Is it continuous delivery or continuous deployment? (c) What would change to turn it into the other type of CD?

See solution
  • (a) Step (1) —running the suite on every PR— is CI: verify on every change. Steps (2) and (3) —package, leave ready, and send to production— are CD: moving the verified code to its destination.
  • (b) It's continuous delivery (Continuous Delivery). The clue is step (3): the final send to production is triggered by a human with a click. The pipeline automates almost everything, but leaves the final decision of "now to production" in a person's hands.
  • (c) To turn it into continuous deployment (Continuous Deployment), you'd have to remove the human click from step (3): so that, as soon as CI goes green and the app is packaged, the pipeline deploys it to production automatically, without intervention. That demands much more confidence in the suite, because there's no longer a human reviewing before the send.

The lesson: the only difference between continuous delivery and deployment is who presses the final button: a human (delivery) or no one/automatic (deployment). Both lean equally on a solid CI underneath.

Exercise 3 — Where this guide ends. A teammate says: "since we're in CI/CD, in module 8 we should deploy Reservo to production automatically". Explain why that's outside this guide's boundary, using two distinct reasons from the lesson.

See solution

Two reasons why deploying Reservo is outside the guide:

  1. The declared focus is the CI of the tests, not deployment. The guide teaches running your suite on every change and protecting the green branch; deployment to production (CD) is a separate world —packaging, servers, databases, secrets, rollback, monitoring— that isn't testing and would dilute the focus. The guide places CD, it doesn't teach it.
  2. Reservo doesn't have an app to deploy. Reservo is pure logic with no server or database —on purpose, to learn testing without infrastructure in the middle—. There's no "the Reservo service" to send to production, so there wouldn't even be anywhere to honestly demonstrate deployment. Module 8 assembles Reservo's complete CI pipeline (suite, matrix, coverage, cache), which is the capstone coherent with what the guide does teach.

(Also accepted: continuous deployment demands a suite you fully trust, and building that confidence is exactly what the guide teaches first; deployment comes after mastering CI.)

The lesson: "CI/CD" in the title doesn't promise to teach deployment; it promises the foundation —CI— that any CD leans on. Knowing where the boundary is keeps you from expecting from the guide something it very deliberately leaves for another path.

Summary and next step

In this lesson you separated the two halves of "CI/CD". CI —which you already master— is verifying: running the suite on every change so only working code gets through, the green main branch. CD is what comes after: sending that already-verified code toward its destination —staging or production—. CI is the factory's quality control; CD is the delivery fleet that only loads what has a stamp. And CD depends on CI, because you don't send what you didn't verify.

You saw that CD has two senses on a ladder of automation: continuous delivery, which leaves the code ready and waits for a human click for the final send; and continuous deployment, which sends to production only if CI goes green, without intervention —more automatic and more demanding of the suite's quality—. The three acronyms share the same foundation, CI, and that's why they're written together. And you understood the guide's boundary: here the CI of the tests is taught in depth, and CD is placed but not developed, because deploying is another world and Reservo, being pure logic, has no app to deploy.

Before moving on you should be able to: distinguish CI from CD in one sentence (verify vs send); explain why CD depends on CI; differentiate continuous delivery from continuous deployment by "who presses the final button"; and say why this guide stays on the CI side.

What's next is pulling the whole module into your hands. In lesson 8, the mini-project, you'll take your own manual Reservo testing flow and map each step to the pipeline stage that would automate it, identifying the "on my machine" risk that a clean environment erases —and being ready, with the problem and the concept already clear, to write your first real workflow in module 2—.

Resources