One push to the repo, and a machine builds your app, tests it, and ships it — no humans, no 'I'll do it tonight'.
← / → to navigate · EN/VI switch below
Before CI/CD, every deploy was an event: someone had to remember the steps, do them in order, and hope.
Restart the server? Swap the files? Run the migration? The recipe lives in someone's head and in a wiki nobody updates.
'It works on my machine, I'm sure.' Under deadline pressure, the test step is the first thing that quietly disappears.
The first person to notice a bug is a customer, on production, at 2 a.m. Not a test, not a teammate.
Deploys pile up, changes get big, and every ship carries more risk than it should.
CI/CD = an automated pipeline: whenever code changes, the machine builds it, tests it, and deploys it — the same way, every time.
A recipe of steps that runs automatically on a machine in the cloud. You push code; the belt does the rest.
On every commit: build the app and run the tests. Breakage is caught in minutes, not weeks.
When the tests pass, push the result to staging or production — automatically, or with one click.
No special 'deploy day'. Every push to the repo triggers the same pipeline — small, frequent, boring. Boring is good.
Two ideas, one pipeline. CI asks 'is it safe?'; CD says 'make it so'.
Build + test on every commit. The moment your change breaks something, the pipeline turns red and the deploy stops.
Goal: small, frequent changes; breakage found in minutes.
A passing pipeline ends with deployment: the new version goes to staging (or straight to production). Always the same path.
Goal: the app is deployable at any moment — because it just was.
One push to the repo, and the machine walks this belt from left to right. Any red step stops everything.
Between 'git push' and 'it's live', the machine does these four things — every single time, in the same order.
The machine fetches the exact commit you pushed — same bytes, same versions, no 'which version was it again?'
A clean machine installs Python and your dependencies from requirements.txt. No 'it worked on my box' excuses.
Your test suite runs. One failing test = red pipeline = nothing ships. This is CI doing its job.
The app becomes a container image, and the new image is deployed to the server. Staging first, production after — automatically.
This is the whole 'deploy' — a log that scrolls by itself while you do something else.
A test fails — so the bad code never reaches the server. You get the error in minutes, not a customer at 2 a.m.
On GitHub, the whole magic is one file: a few lines of YAML describing the steps.
This file lives in your repo at .github/workflows/. GitHub runs it automatically every time you push to main.
# runs automatically on every push
name: build-test-deploy
on:
push:
branches: [main]
jobs:
ship:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4 # 1. get the code
- run: pip install -r requirements.txt # 2. deps
- run: pytest # 3. test
- run: docker build -t myapp . # 4. build image
- run: ./deploy.sh # 5. ship it
on: push = when · jobs = what · steps = in what order.
Every GitHub Actions workflow is just these three ideas. The rest is vocabulary.
'When does this run?' on: push = every push to the repo. Other options: on a schedule, on a pull request, on a tag.
A job is a named chunk of work that runs on a fresh machine — runs-on: ubuntu-latest. Here, one job named ship does everything.
Ordered commands, top to bottom: - uses: runs a ready-made step (checkout), - run: runs one shell command. The first failure stops the rest.
The final step does the boring part — once written, it runs itself forever.
# deploy.sh — runs on the server
docker pull myapp:latest # newest image
docker stop web || true
docker rm web || true
docker run -d --name web -p 8080:5000 myapp:latest
curl -fsS http://127.0.0.1:8080/health
Stop the old container, start the new one, knock on the door to check it answers.
Same idea, different homes. This course uses GitHub Actions — the others are named so you recognize them in the wild.
| Tool | Where it lives | What to know |
|---|---|---|
| GitHub Actions | GitHub — home of this course's repos | YAML files in your repo (.github/workflows/). Free for public repos. This course's pick. |
| GitLab CI | GitLab — cloud or self-hosted | Same idea, config in one .gitlab-ci.yml file. Common where companies self-host. |
| Jenkins | Your own server — the veteran | A program you install yourself, around since 2011. Pipelines in code or UI. Still everywhere in big companies. |
It's not about speed alone. It's about removing a whole class of scary human moments.
Deploys happen by the pipeline, not by a hero's calendar. You push; the belt handles the rest.
Same steps, same machine, same order — for the 3-line tweak and the big feature. Repetition kills 'works on my machine'.
Push → green or red in minutes. You find out your change broke something before a user ever can.
Because shipping is boring and automatic, changes stay small and frequent. That's how teams ship daily without fear.
One sentence about the whole topic: the machine walks the belt, you just push.
git push
the only human stepcheckout → install → test → build → deploy
the conveyor beltnew version is live
automated · tested · repeatablepush → pipeline → live. No deploy days, no forgotten steps, no 'works on my machine'.
push → build → test → deploy, on every change. The belt runs; you ship.