CI/CD with GitHub Actions
- Explain the anatomy of a GitHub Actions workflow: events, jobs, steps, runners
- Build a test โ eval-gate โ build โ push โ deploy pipeline for the capstone
- Use caching, environments, and secrets to make CI fast and safe
- Wire the Day-141 eval gate and a deployment/rollback plan into the pipeline
| Spaced-rep warm-up: eval-gate + Docker cards (D141/D148) | 10 min |
| ELI5 + tech read: workflow anatomy, the pipeline, protection | 20 min |
| Guided: test+eval-gate pipeline, then build/push/deploy | 42 min |
| Practice: protection + rollback policy | 15 min |
| Project: automate the capstone pipeline end to end | 23 min |
| Quiz + flashcards | 10 min |
Builds on: Day 141 โ Regression gates & CI for AI ยท Day 148 โ Docker fundamentals ยท Day 151 โ Deploy lab โ container to cloud URL
Imagine a tireless release manager who watches your repository. Every time you push code, they run the whole checklist before anyone can ship: run the tests, run the AI eval gate, build the container, scan it, push it to the warehouse, and โ if every box is ticked โ deploy it and tell the team. They never forget a step, never skip the tests because it's Friday, and never deploy a broken build because "it's probably fine." They do the exact same routine every single time.
That robot is a CI/CD pipeline, and GitHub Actions is one way to hire it. CI (continuous integration) is the first half โ on every push, automatically verify the change is sound (tests pass, evals hold, image builds). CD (continuous delivery/deployment) is the second half โ automatically ship the verified build to staging or production. You've already met the pieces: the Day-141 eval gate, the Day-148 image build, the Day-151 deploy. Today you hand the whole sequence to the robot so shipping stops being a nervous manual ritual and becomes a boring, repeatable event โ which is exactly what "boring" should mean in production: safe.
Manual deploys are where outages are born: a skipped test, a forgotten build step, a secret typed wrong at 6pm. CI/CD makes the safe path the only path โ the eval gate you built on Day 141 is worthless if a teammate can merge around it, and a pipeline is what makes it unavoidable. For an FDE, an automated pipeline is also a trust artifact: showing a customer that every change runs tests and evals and can roll back in one click is what gets you past their change-management review (Day 169). And it's a direct interview topic โ "walk me through your CI/CD for an LLM app" is a 2026 staple, and the differentiator is that your pipeline gates on *evals*, not just unit tests.
The robot release manager โ a push rides the pipeline, and one gate bites
step 1 / 5You push a prompt change to main. From here, no human touches the release โ the pipeline decides. First stop: the classic test suite.
Guided practice
Build the test + eval-gate pipeline
22 min- In your capstone repo, create
.github/workflows/deploy.ymlwith (for now) thetestandeval-gatejobs from the tech section. - Add
ANTHROPIC_API_KEYas a repository secret (Settings โ Secrets and variables โ Actions). Confirm it is referenced only assecrets.ANTHROPIC_API_KEY, never printed. - Push a branch and open a PR. Watch both jobs run in the Actions tab;
eval-gateshouldneedtestand only start after it passes. - Prove the gate bites: on the branch, sabotage a prompt so the eval gate fails, push, and confirm the PR shows a red check and cannot merge (after you set branch protection in the next step).
- Turn on branch protection for
main: require thetestandeval-gatechecks to pass before merge. Now the tripwire is unavoidable โ verify a failing gate blocks the merge button.
Add build, push, and a deploy step
20 min- Extend the workflow with the
build-pushjob: log in to ghcr.io with the auto-providedGITHUB_TOKENand build+push the image taggedsha-<github.sha>usingdocker/build-push-actionwith GitHub Actions layer caching. - Push to
main(via a merged PR) and confirm the image appears in your repo's Packages, tagged by the commit SHA. - Add the
deployjob targeting astagingenvironment. Wire it to your Day-151 platform's deploy mechanism โ most PaaS platforms give a deploy hook URL or a CLI action; store the hook/token as an environment secret and call it, passing the SHA-tagged image. - Merge a trivial change and watch the full chain run: test โ eval-gate โ build-push โ deploy. Hit the staging URL and confirm the new version is live.
- Practice rollback: re-run the deploy step (or trigger it via
workflow_dispatch) pinned to the *previous* SHA and confirm staging reverts. Note the exact steps in your runbook.
On your own
Design the protection + rollback policy
15 minWrite .github/PIPELINE.md documenting the pipeline's guarantees. Specify: (1) which checks are *required* to merge to main (tests, eval-gate) and why the eval gate must be a required check, not just a job; (2) the environment protection on staging vs production (which branches deploy, whether production needs a manual approval and reviewer); (3) exactly how rollback works with SHA-tagged images โ the command or click sequence to redeploy the last good SHA, and how you identify it; (4) what the pipeline deliberately does NOT do yet (e.g. auto-deploy to production) and why that's a conscious choice. Then verify claim (1) by opening a PR with a failing eval and confirming the merge button is actually blocked.
Hints: a job that runs but isn't a *required status check* can be merged around โ the branch-protection setting is what turns the gate from advisory into mandatory.
Automate the capstone pipeline end to end
Give the capstone a real CI/CD pipeline. Commit .github/workflows/deploy.yml implementing test โ eval-gate โ build-push โ deploy, with pip and Docker-layer caching, secrets from the repo/environment store, SHA-immutable image tags, and a staging environment. Configure branch protection so the test and eval-gate checks are required to merge to main โ the Day-141 tripwire made unavoidable. Deliver .github/PIPELINE.md documenting the stages, the protection rules, and the rollback procedure. Prove it works with evidence: a screenshot/log of a PR blocked by a failing eval gate, a successful main-branch run that pushes a SHA-tagged image and deploys to the staging URL, and a demonstrated rollback to a previous SHA. The deployed staging service must answer a real query.
Common mistakes & misconceptions
- Running the eval gate as a job but not a required status check. If branch protection doesn't require it, anyone can merge around a red gate โ the setting, not the job, is what makes it mandatory.
- Building and deploying on every PR. PRs should run tests + evals; guard build/deploy with if: github.ref == main so feature branches don't ship.
- Deploying the :latest tag from CI. Tag by github.sha so the deployed artifact is reproducible and rollback targets a specific build (Day 149).
- Echoing secrets in a run step for debugging. Secrets are masked in logs but printing them defeats that; reference them only as env from secrets.NAME.
- No caching. Reinstalling dependencies and rebuilding every Docker layer from scratch makes CI slow enough that people disable it โ cache pip and use type=gha for layers.
- No documented rollback. A pipeline that only knows how to go forward is half a pipeline; because images are SHA-tagged, rollback is redeploying the previous SHA โ write it down.
Q1. What actually makes the eval gate unavoidable for merges to main?
Q2. Why tag the image built in CI with `github.sha` rather than `latest`?
Q3. Your pipeline should build and deploy only from main, but run tests and evals on every PR. How is that expressed?
Go deeper โ curated resources
- GitHub environments & deployment protection rules โ โ Add a production environment requiring a manual approval and a reviewer, then make deploy-to-prod a separate gated job โ the pattern Day 154 and Day 161 build on.
- Workflow runs test โ eval-gate โ build-push โ deploy with correct ordering
- Branch protection makes the eval gate a required check; a failing gate blocks merge (shown)
- CI pushes a SHA-tagged image and deploys to a staging URL that answers a real query
- Rollback to a previous SHA demonstrated; PIPELINE.md documents protection + rollback
- Quiz โฅ 2/3
โ Back: This makes the Day-141 eval gate unavoidable via branch protection, builds the Day-148/149 image, pushes the Day-149 SHA tags, and automates the Day-151 deploy.
Forward โ: Day 153 provisions the deploy target as code so the whole environment is reproducible; Day 154 makes push-to-main deliver a full staging pipeline; Day 158 turns the SHA-rollback into an incident playbook, and Day 169 shows this pipeline to a customer's change-management review.
Unlocks: D153 Infrastructure as Code & Environments ยท D154 Week 22 Checkpoint: Staging Pipeline