Capstone: retire Release Night
Put it all together for Byte Bakery: run commits through the full delivery pipeline, gate production releases, and report the DORA metrics week by week.
- Model a complete delivery pipeline from commit to production
- Combine pipeline, security, reliability and timing checks into a release gate
- Report delivery performance over time to show improvement
Six months after you joined, Byte Bakery holds its last Release Night - as a party, with pizza and no laptops. Every change now flows through one pipeline: build, test, scan, deploy to staging, smoke test, deploy to production. Infrastructure lives in Terraform, production state in Git, alerts follow SLOs, and incidents end with blameless postmortems.
In this capstone you’ll build the three tools that keep it honest:
- The pipeline runner - runs each commit through the stages, stopping at the first failure, and only deploys from
main. - The release gate - decides whether a release may go to production right now, from the pipeline, vulnerabilities, incidents, the error budget, the deploy window and freeze dates.
- The delivery dashboard - turns a deployment log into weekly DORA metrics with trends, so the team can see itself improving.
Try it
The whole pipeline
This is Byte Bakery’s pipeline today, from commit to production.
- What is the critical path? Which job would you speed up first?
- Make smoke-staging fail. Does anything reach production?
- Make deploy-production fail. What happens next?
- ✓ success0-1 min
- ✓ success0-4 min
- ✓ success0-1 min
- ✓ success4-7 min
- ✓ success7-9 min
- ✓ success9-11 min
- ✓ success11-13 min
- ✓ success13-16 min
- ⊘ skipped
- ✓ success16-17 min
Click a job to make it fail (click again to fix it). Bars show when each job runs; jobs without a dependency between them run at the same time.
1name: Deliver
2on:
3 push:
4 branches: [main]
5
6permissions:
7 contents: read
8 id-token: write # OIDC: short-lived cloud credentials, no stored keys
9
10jobs:
11 build:
12 runs-on: ubuntu-latest
13 outputs:
14 image: ${{ steps.push.outputs.image }}
15 steps:
16 - uses: actions/checkout@v4
17 - run: pip install -r requirements.txt && ruff check . && pytest
18 - id: push
19 run: |
20 image=registry.example.com/byte-bakery/shop:${{ github.sha }}
21 docker build -t "$image" . && docker push "$image"
22 echo "image=$image" >> "$GITHUB_OUTPUT"
23 - run: trivy image --exit-code 1 --severity CRITICAL,HIGH registry.example.com/byte-bakery/shop:${{ github.sha }}
24
25 promote:
26 needs: build
27 runs-on: ubuntu-latest
28 environment: production # protection rules and the release gate live here
29 steps:
30 - uses: actions/checkout@v4
31 with:
32 repository: byte-bakery/deployments
33 - run: |
34 yq -i '.image = "${{ needs.build.outputs.image }}"' environments/production/shop/values.yaml
35 git commit -am "Deploy shop ${{ github.sha }}" && git push # GitOps: Argo CD does the restNotice how the pieces from the track fit: CI builds one artifact tagged with the commit SHA, scans it, and promotion is a commit to the GitOps repository - Argo CD rolls it out, alerts watch the burn rate, and a bad release is a git revert away.
1checks = [
2 ("pipeline is green", True, "block"),
3 ("no open SEV1 or SEV2 incidents", True, "block"),
4 ("error budget above 25%", False, "warn"),
5]
6failed = [(name, kind) for name, passed, kind in checks if not passed]
7blockers = sum(1 for _, kind in failed if kind == "block")
8print("NO GO" if blockers else f"GO WITH CAUTION ({len(failed)} warning)" if failed else "GO")GO WITH CAUTION (1 warning)
Where to go next
You’ve covered the DevOps journey end to end. To keep going:
- Build a real pipeline for a side project: GitHub Actions or GitLab CI, a container image, and a deploy to a free tier.
- Write Terraform for a small cloud setup, run plans in pull requests, and break something with drift on purpose.
- Read The Phoenix Project (a novel!), The DevOps Handbook, Accelerate and Google’s free Site Reliability Engineering books.
- Try the GitHub, Docker, Kubernetes, Microservices and Distributed Systems tracks for deeper dives into the tools.
Key takeaways
One pipeline: build once, test, scan, deploy to staging, verify, promote to production.
Release gates combine pipeline health, security, incidents, error budgets and timing.
Measure delivery over time with the DORA metrics, and use the trends to improve.
The goal is boring deploys: small, automated, observable and easy to undo.
Lesson quiz
7 questions · pass with 5 correct · up to 50 XP
Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.
Practice: automate DevOps chores in Python
Write the small Python tools DevOps teams really build - pipeline runners, plan checkers, metric calculators, scanners - and run them against sample inputs. They run locally in your browser; no servers or cloud accounts needed.
Run commits through the pipeline
The first input line lists the stages in order, like lint test build scan deploy-staging smoke deploy-prod. Each following line is a commit: sha branch followed by any stage results that aren’t passes, like test=fail.
Run each commit’s stages in order, stopping at the first failure. The first stage whose name starts with deploy, and every stage after it, only run on main; on other branches the pipeline ends just before it. Print a1b2c3 (main): lint:ok test:ok build:ok scan:ok deploy-staging:ok smoke:ok deploy-prod:ok -> released, with stage:FAIL -> failed at test for a failure (adding , roll back when a deploy stage failed), or -> ready to merge for other branches.
Finish with released 2 of 5 commits; main is green - main is green if the last commit on main was released (or there were none).
- A busy morning
- Bad deploys
Python runs in a sandboxed browser worker with a 60 second time limit. Its runtime loads from the Pyodide CDN; your code stays in this browser.
Build the release gate
Each input line is key value, with the keys date (YYYY-MM-DD), weekday (Mon to Sun), time (HH:MM), pipeline (green/red), blocking_vulnerabilities, open_sev1_sev2, error_budget_left (a percentage), freeze (START..END dates, or none) and hotfix (yes/no). Run these checks in order, printing each as its level padded to 5 characters, a space and the message - ok pipeline is green, WARN ... or BLOCK ...:
pipeline is green/ BLOCKpipeline is redno blocking vulnerabilities/ BLOCK3 blocking vulnerabilitiesno open SEV1/SEV2 incidents/ BLOCK1 open SEV1/SEV2 incident(s): finish the incident first- error budget:
error budget 40% left(ok at 25% or more); WARNerror budget 12% left: ship small changes behind a canary; at 0 or less BLOCKerror budget exhausted: reliability fixes only- unless it’s a hotfix, which makes it a WARN. - deploy window: ok
inside the deploy windowon Mon-Fri from 09:00 up to (not including) 16:00; otherwise WARNoutside the deploy window: make sure someone is around to watch. - freeze: ok
no change freeze; inside the freeze dates (inclusive) BLOCKchange freeze until 2027-01-02, or WARNchange freeze until 2027-01-02 (hotfix allowed)for a hotfix.
Finish with decision: GO, decision: GO WITH CAUTION (2 warnings) or decision: NO GO (1 blocker) (singular or plural as needed).
- Tuesday morning
- Friday afternoon
- Holiday freeze
- Hotfix in the freeze
Python runs in a sandboxed browser worker with a 60 second time limit. Its runtime loads from the Pyodide CDN; your code stays in this browser.
Build the delivery dashboard
Each input line is a deployment: week team lead_time_hours ok|failed. For each team (alphabetically) print the team name, then each of its weeks in order as week 1: 3 deploys, median lead 6.0 h, 33% failed.
From the second week on, compare with the team’s previous week: add (up), (down) or (same) after the deploy count, (faster), (slower) or (same) after the lead time, and (better), (worse) or (same) after the failure rate - like week 2: 5 deploys (up), median lead 4.0 h (faster), 20% failed (better). Compare the rounded numbers as printed.
- Six weeks in
Python runs in a sandboxed browser worker with a 60 second time limit. Its runtime loads from the Pyodide CDN; your code stays in this browser.
Questions about this lesson
Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.
Loading posts…