What a pipeline is for
CI, continuous delivery and continuous deployment, the stages every pipeline shares, why you build once and deploy many, and how environments keep production safe.
By the end of this lesson you'll be able to
0 of 4 completeThe problem a pipeline solves
Without a pipeline, a release looks like this: someone pulls the latest code on their laptop, runs the tests they remember, builds it, copies it to the server and restarts the app. It works until the day they forget a step, build from the wrong branch, or are on leave.
A pipeline is that same list of steps, written down as code and run by a machine on every change. It never forgets a step, it runs the same way every time, and it tells you within minutes when a change breaks something, while the change is still fresh in your head.
CI, continuous delivery and continuous deployment
"CI/CD" is three ideas, and people mix them up all the time:
| Term | What happens automatically | Who sends it to production |
|---|---|---|
| Continuous integration | Every push is merged into the main line, built and tested | Not covered |
| Continuous delivery | Every passing change is packaged and ready to release | A person, with one click |
| Continuous deployment | Every passing change goes all the way to production | Nobody: the pipeline does |
CI is the habit: small changes, merged often, each one checked. Continuous delivery adds packaging and deploying to test environments, so releasing is a non-event. Continuous deployment removes the last manual click. Most teams start with delivery and move to deployment once they trust their tests.
The stages of a pipeline
Almost every pipeline you'll meet has the same shape, whatever tool runs it:
- Trigger. A push, a pull request, a tag or a schedule starts the run.
- Lint and static checks. Formatting, style, type checks. Seconds.
- Test. Unit tests, then the slower integration tests.
- Build. Turn the code into something deployable: the artifact.
- Publish. Store the artifact in a registry, tagged with a version.
- Deploy. To staging first, then to production.
Each stage only runs if the one before it passed. That's the whole idea, and you can see it with two commands in any shell:
$ false && echo deployed # false fails, so the second command never runs $ true && echo deployed # true succeeds, so it does deployed
false && echo deployedfalsedo nothing, and fail&&run the next command only if this one workedechoprint textdeployeda value the command works on
true && echo deployedtruedo nothing, successfully&&run the next command only if this one workedechoprint textdeployeda value the command works on
Fail fast: put the cheapest check that can catch a mistake first. A missing semicolon should fail in 10 seconds of linting, not after an 8-minute build.
Here's what that looks like in GitHub Actions, the tool the next lessons use. Don't worry about every line yet; notice the trigger, the job, and the steps running in order:
# .github/workflows/ci.yml name: ci on: push: branches: [main] pull_request: jobs: check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 # get the code - uses: actions/setup-node@v7 with: node-version: 22 - run: npm ci # install exact versions from the lock file - run: npm run lint # cheapest check first - run: npm test - run: npm run build
Artifacts: build once, deploy many
An artifact is what the build produces and what you actually deploy: a Docker image, a
.jar, a binary, or a folder of static files. It gets a version (a tag, a commit SHA, or for
images a digest) and lives in a registry or artifact store.
The rule that follows: build it once, then deploy that same artifact everywhere. If you rebuild for production, you might pick up a new base image or a new dependency version, and production ends up running something that never went through staging.
| Do | Don't |
|---|---|
Build once, tag it app:3f9c2a1, promote that tag | Rebuild from the same commit per environment |
| Put environment differences in config and secrets | Bake the database URL into the artifact |
Environments
An environment is a place your app runs, with its own config, data and access rules:
- Development: where you try things. Breaking it is fine.
- Staging: as close to production as you can afford. The last check with real infrastructure.
- Production: real users and real data. Changes arrive only through the pipeline.
The artifact moves up this ladder, and only the config changes. Moving it from one environment to the next is called promotion. Production usually has a gate: a required approval, a deploy window, or both.
Design the pipeline for a small web app
Your team has a Node.js API with ESLint, unit tests and a Dockerfile. Releases are manual and someone broke production last week by deploying the wrong branch. Write ~/pipeline-plan.md: the trigger, each stage in order with what it checks, the artifact and its tag, and how a change reaches production.
~/pipeline-plan.mdReveal one safe solution
# Pipeline: payments-api Trigger: every pull request (checks only) and every push to main (full pipeline). 1. Lint: `npm run lint`, 15 s. Fails on style or obvious bugs. 2. Unit tests: `npm test`, 2 min. 3. Build: `docker build`, tag the image with the commit SHA, e.g. `payments-api:3f9c2a1`. 4. Publish: push that image to the registry. 5. Deploy to staging: automatic, then a smoke test hits /health. 6. Deploy to production: the same image tag, after one approval in the pipeline. Only the pipeline can deploy. Config and secrets come from each environment, never the image.
The wrong-branch problem goes away because production only accepts what main built, and the staging-tested image is the one that ships.
Try it yourself
0 of 5 steps doneRun each task in your own account or terminal, then tick it off.
Quick check
Every change that passes the pipeline is ready to release, but a person clicks "deploy" to send it to production. What is that called?
Official reading for this lesson
- ArticleContinuous IntegrationMartin Fowler
- ArticleContinuous DeliveryMartin Fowler
- GuideThe Twelve-Factor App: build, release, run12factor.net
- DocsUnderstanding GitHub ActionsGitHub Docs
- DocsWorkflow syntax for GitHub ActionsGitHub Docs
- DocsManaging environments for deploymentGitHub Docs
- GuideDORA research on software delivery performanceDORA
Or get every quiz answer right and it completes itself.