Lesson 6 · Build, deploy & trunk-based delivery
Trunk-based deployment
The tbd.* model — from a single shared branch to a deploy in every env×org cell.
Your win: explain trunk-based development, read this repo's full deploy chain (the thing a lot of people get wrong), and see how one deploy fans out across the env×org matrix with an authorization gate.
Trunk-based development — the model CI/CD is built for
In trunk-based development, everyone integrates into one shared branch (the
trunk, here develop) in small, frequent changes behind short-lived
branches.1 No long-lived release branches drifting
apart. That's why the deploy workflows are prefixed tbd. — trunk-based
deploy.
The full chain (the part people get wrong)
You met this in Lesson 1; now the anchors. A merge does not deploy — a release tag does, and a cron picks it up:
schedule: cron: "0 0-13/2 * * 1-5" (every 2 hours, Mon–Fri). It fetches the latest
trunk tag and runs gh workflow run tbd.build.yaml … {"be_release_tag": "…",
"auto_deploy": "true"} (:45). So staging deploys
on a timer, not on merge. Production is a manual
workflow_dispatch of tbd.deploy.yml.
Fan-out: one deploy, every env×org cell
deploy-k8s job
(.github/workflows/tbd.deploy.yml:360-390) uses a
strategy.matrix.organization over
{manabie, jprep, tokyo, synersia, renseikai, ga}
(:370-371) — one job per org, in parallel — with per-org
concurrency: cancel-in-progress: false (:373-375)
so a running deploy is never cancelled mid-rollout. This is the env×org matrix from
Course 1, realised as a CI matrix.
privileges-check
step (tbd.deploy.yml:211-213, the
tbd.privileges-check action) verifies the actor is allowed to release to that
env/org. Note: this is a custom action, not GitHub's native "Environments +
required reviewers" feature — a deliberate choice to encode the org's release policy in code.
Trunk-Based Development + GitHub Environments
The branching model, and GitHub's native environment protection (the alternative to the repo's custom gate).
→ trunkbaseddevelopment.com
→ docs.github.com — Managing environments
Check yourself (from memory)
Q1. In trunk-based development, everyone integrates into…
develop), small frequent merges behind
short-lived branches. Hence tbd.* = trunk-based deploy.
Q2. Staging deploys are triggered by…
Q3. One deploy reaches many orgs via…
strategy.matrix.organization fans one deploy into
one job per org, gated by privileges-check.
develop) in small frequent changes; tbd. = trunk-based deploy.
CHAIN (merge does NOT deploy): push→develop → tbd.create_release_tag (cut tag) →
2h cron 0 0-13/2 * * 1-5 (tbd.auto-deploy-staging.yml)
gets latest tag → gh workflow run tbd.build.yaml auto_deploy=true → build →
tbd.deploy.yml. STAGING = cron-auto; PROD = manual workflow_dispatch.
WHY cron: batch merges into one deploy (throughput/latency trade-off). FAN-OUT: deploy-k8s
uses strategy.matrix.organization over {manabie,jprep,tokyo,synersia,renseikai,ga},
per-org cancel-in-progress:false (never cancel a live deploy) — the env×org matrix
as a CI matrix. GATE: tbd.privileges-check action (not GitHub Environments).1. Trunk-Based Development; in-repo .github/workflows/tbd.auto-deploy-staging.yml, tbd.deploy.yml.