CD7: CI pipelines with GitHub Actions
Continuous integration, and how GitHub Actions works
🎯You'll be able to
Explain what continuous integration is for, and read a GitHub Actions workflow: events, jobs, steps and runners.
🏠The everyday picture
In a restaurant kitchen, the head chef tastes every dish before it leaves the pass. Catching too much salt at the pass is cheap; catching it after the customer's complained is not. And tasting each dish as it's made is easier than tasting a whole day's food at closing time.
📘What it really is
-
Continuous integration (CI) means merging small changes often into the main branch, with automatic checks on each one: build, tests, formatting, security scans. Problems are found minutes after they're written, while the change is small and fresh in mind.
-
GitHub Actions runs workflows defined in YAML files in
.github/workflows/: - events start them:
pull_request(a pull request is opened or updated),push(commits arrive on a branch),schedule(a timer, for example nightly drift checks),workflow_dispatch(a button); - a workflow has jobs, which run in parallel unless one
needsanother; - each job runs on a runner, a fresh virtual machine such as
ubuntu-24.04hosted by GitHub, or a self-hosted runner on your own server; -
a job has steps: either
run:(shell commands) oruses:(a reusable action, such asactions/checkout, which fetches the code). -
Status checks: each job's result shows on the pull request. Branch protection rules (or rulesets) can require them to pass before merging, which turns "please run the tests" into "the tests must pass".
-
Continuous delivery and deployment (CD8) extend the pipeline past the checks to releasing.
📝A worked example
Input: the start of RouteRani's finished .github/workflows/ci.yml:
on:
pull_request:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 22
- name: API tests
working-directory: app
run: |
npm ci --no-audit --no-fund
npm test
Expected output: on every pull request and every push to main, GitHub starts a fresh Ubuntu machine, checks out the code, installs
Node.js 22 and runs the API's tests. The pull request shows a test check that turns green or red. (Not run on GitHub for this course.)
🌍Where it's used
- Open-source projects check every contribution before a maintainer looks at it.
- Large companies run tens of thousands of tests per change, often split across many runners.
- Infrastructure teams run
terraform fmt,validateandplanon every pull request (CD4).
📝Case scenario
A bank's mobile team merged a month of work at once before each release. Each merge broke dozens of tests, and untangling which change caused which failure took a week. They moved to small pull requests with CI checks on each, required to pass before merging. Release week became a normal week.
🖱️Try it
Open the starter's .github/workflows/ci.yml and list: the events, the jobs, which job depends on which, and which runner each uses. Success:
you notice the starter's deploy job doesn't depend on test and runs on pushes to any branch.
⚠️Common mistakes
- Checks that aren't required. Sign: red pull requests merged anyway. Fix: make the checks required in branch protection.
- Long-lived feature branches. Sign: painful merges and late surprises. Fix: small, frequent pull requests.
- Tests only on
main. Sign: broken code found after merging. Fix: run checks onpull_requesttoo.
🛠️For your project
Project 2 test 1 checks the workflow runs on pull requests and on pushes to main only.
✅Quick check
What runs jobs in GitHub Actions?
Show the answer
Runners: fresh virtual machines hosted by GitHub, or self-hosted servers.
How do you make a job wait for another?
Show the answer
With needs: <job name>.
