Lesson 8 · Build, deploy & trunk-based delivery

The deploy mechanism

The last mile — how a workflow actually pushes the image into GKE, and why it waits.

Your win: trace exactly what the deploy job runs (it's the skaffold/helm you already know, automated), and explain the push-based model's one real weakness — drift.

Deploy = the same Skaffold/Helm, run by CI

Here's the satisfying part: the deploy step is nothing new. It's Course 1's skaffold and Course 3's helm upgrade, run for you by a GitHub Actions job instead of from your laptop.

Anchor — .github/actions/tbd.deploy-backend/action.yml Per org, the deploy action: installs skaffold + gets GKE credentials (setup-k8s), checks out the release tag, resolves the env/org config, and then runs (:91-92):
(cd deployments/helm/platforms/nats-jetstream && skaffold deploy)
skaffold deploy -f skaffold.backend.yaml
with TAG=${be_release_tag} and SKAFFOLD_STATUS_CHECK: 'true' (:87). That skaffold deploy is helm upgrade --install under the hood (Course 3 L8), rendering the per-service subcharts with the right {env}-{org}-values.yaml and stamping in the image tag.
Why SKAFFOLD_STATUS_CHECK: true matters With status-check on, the deploy waits for the rollout to be healthy — readiness probes passing (Course 2 L8) — before reporting success. So a deploy that would leave pods crash-looping fails the job instead of silently "succeeding." The pipeline's green tick means "it's actually running," not just "the command returned."

Push-based — the model and its weakness

This is the push-based delivery from Lesson 1, now concrete: a workflow runs skaffold deploy against the cluster. There's no controller continuously reconciling — the cluster changes only when this job runs.

Drift: the cluster can silently diverge from git Because reconciliation happens only at deploy time, anything changed out-of-band (a hotfix kubectl edit, a manual scale) persists until the next deploy overwrites it. A GitOps controller (Argo/Flux) would revert such drift continuously; a push-based system doesn't. The upside is simplicity and an explicit "deploys happen when we say"; the cost is that "what git says" and "what's running" can diverge between deploys. This is the trade-off from Lesson 1, seen from the deploy side.
Rollback, the push-based way To roll back, you don't run helm rollback by hand — you re-deploy an older release tag via workflow_dispatch (git remains the source of truth). Because the image tag = the release tag (Lesson 5), "roll back to yesterday" is "deploy yesterday's tag." Clean and auditable.
Read this next

Skaffold — deploy + CI/CD

How skaffold deploy renders and applies (via Helm), and the status-check that waits for readiness.

skaffold.dev — Helm deployer
skaffold.dev — CI/CD

Check yourself (from memory)

Q1. The deploy job's core command is…

skaffold deploy -f skaffold.backend.yaml — the Course-3 helm upgrade --install, run by CI per org.

Q2. SKAFFOLD_STATUS_CHECK: true makes the deploy…

It blocks on readiness, so a crash-looping rollout fails the job instead of a false green.

Q3. The weakness of push-based delivery is…

Reconciliation only happens at deploy time; an out-of-band change persists until the next deploy overwrites it.
The deploy mechanism + the push-based trade-off.
recall, then click to reveal
DEPLOY = Course 1/3's tools, run by CI. tbd.deploy-backend action per org: install skaffold + GKE creds (setup-k8s), checkout the release tag, then skaffold deploy -f skaffold.backend.yaml (= helm upgrade --install) with TAG=be_release_tag and SKAFFOLD_STATUS_CHECK: true (WAITS for the rollout to be healthy — readiness probes — so a crash-loop FAILS the job, not a false green). PUSH-BASED: a workflow RUNS the deploy; no continuous reconciler. WEAKNESS = DRIFT: out-of-band changes (kubectl edit) persist until the next deploy overwrites them (GitOps would revert continuously). ROLLBACK = redeploy an OLDER release tag via workflow_dispatch (image tag = release tag → "deploy yesterday's tag").
✅ Part 2 complete You've followed the artifact out the door: build & push the one image (L5), the trunk-based deploy chain across the env×org matrix (L6), the self-hosted ARC runners it all runs on (L7), and the skaffold deploy → Helm mechanism (L8). Part 3 turns to the security & operations layer: keyless GCP auth, binary authorization, testing at scale, and running the pipeline.
Ready for Part 3 (keyless auth, binauthz, testing, operations)? Or a mock interview across Parts 1–2 — "walk me through a deploy" is a classic. Ask me.

1. In-repo: .github/actions/tbd.deploy-backend/action.yml; Skaffold — Helm deployer.