Day 152 ยท The robot release manager

CI/CD with GitHub Actions

You will be able to
  • 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
Today's ~120 minutes
Spaced-rep warm-up: eval-gate + Docker cards (D141/D148)10 min
ELI5 + tech read: workflow anatomy, the pipeline, protection20 min
Guided: test+eval-gate pipeline, then build/push/deploy42 min
Practice: protection + rollback policy15 min
Project: automate the capstone pipeline end to end23 min
Quiz + flashcards10 min

Builds on: Day 141 โ€” Regression gates & CI for AI ยท Day 148 โ€” Docker fundamentals ยท Day 151 โ€” Deploy lab โ€” container to cloud URL

The analogy

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.

Why this matters on the job

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.

Watch it happen

The robot release manager โ€” a push rides the pipeline, and one gate bites

step 1 / 5
git pushโ†’Testspytestโ†’EVAL GATEgolden setโ†’Builddocker imageโ†’Stagingโ†’Production
โœ‰ 42 unit testsโ€ฆ all green in 90 s

You push a prompt change to main. From here, no human touches the release โ€” the pipeline decides. First stop: the classic test suite.

Guided practice

guided 1

Build the test + eval-gate pipeline

22 min
  1. In your capstone repo, create .github/workflows/deploy.yml with (for now) the test and eval-gate jobs from the tech section.
  2. Add ANTHROPIC_API_KEY as a repository secret (Settings โ†’ Secrets and variables โ†’ Actions). Confirm it is referenced only as secrets.ANTHROPIC_API_KEY, never printed.
  3. Push a branch and open a PR. Watch both jobs run in the Actions tab; eval-gate should need test and only start after it passes.
  4. 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).
  5. Turn on branch protection for main: require the test and eval-gate checks to pass before merge. Now the tripwire is unavoidable โ€” verify a failing gate blocks the merge button.
guided 2

Add build, push, and a deploy step

20 min
  1. Extend the workflow with the build-push job: log in to ghcr.io with the auto-provided GITHUB_TOKEN and build+push the image tagged sha-<github.sha> using docker/build-push-action with GitHub Actions layer caching.
  2. Push to main (via a merged PR) and confirm the image appears in your repo's Packages, tagged by the commit SHA.
  3. Add the deploy job targeting a staging environment. 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.
  4. 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.
  5. 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 min

Write .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.

Ship before you stop

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.

Rubric โ€” check what you completed (0/6)

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.
Knowledge check

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

docsGitHub Actions โ€” documentation โ†—30 mindocsGitHub Actions โ€” quickstart โ†—15 mindocsDocker โ€” build & push with GitHub Actions โ†—20 min
If you have a third hour
Done means
  • 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
How this connects

โ† 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