Lesson 4 · CI/CD & GitHub Actions fundamentals
Reusable workflows & composite actions
Two ways to stay DRY across ~99 workflows — and the one this repo actually chose.
Your win: distinguish a reusable workflow from a composite action (a common
interview question), and read how this repo composes 99 workflows out of 76 shared building
blocks — via composite actions, not workflow_call.
Don't repeat 99 times — two reuse mechanisms
With this many workflows, copy-pasting steps is a maintenance nightmare. GitHub gives two ways to share logic, and picking the right one is the skill:1
| Composite action | Reusable workflow | |
|---|---|---|
| Shaped like | a step (a sequence of steps) | a pipeline (whole jobs) |
| Lives in | .github/actions/<name>/action.yml | .github/workflows/<name>.yml |
| Invoked by | uses: in a step | uses: at the job level |
| Needs | using: composite | on: workflow_call |
| Can it run multiple jobs / gate on environments / take secrets? | no — it's steps in one job | yes — it's a full pipeline |
How this repo does it — composite actions + repository_dispatch
auth-oidc/— authenticate to GCP (Lesson 9)setup-k8s/— GKE credentialstool-install/— install skaffold/helm/jq/yqtbd.build-backend/— build + push + scan + sign the image (Lesson 5)tbd.deploy-backend/— deploy one env/org (Lesson 8)runners/,gcs-cache/,binauthz-sign/,tbd.privileges-check/,slack-alert-*/…
workflow_call) at
all. Where one pipeline needs to trigger another, the repo uses
repository_dispatch — a workflow fires an event that another
workflow listens for (build → deploy in Lesson 1's chain). Composite actions for step-reuse;
dispatch events for pipeline-to-pipeline.
repository_dispatch keeps each pipeline independent and separately triggerable
(you can dispatch a deploy without a build), at the cost of the tighter coupling and typed
inputs a workflow_call would give. Composite actions keep the shared steps in one
place. It's a coherent style — and a good "we chose X over Y because…" story for an interview.
GitHub — Reusable workflows vs composite actions
When each fits, how to author a composite action, and the workflow_call
contract.
→ docs.github.com — Reusable workflows
→ Create a composite action
Check yourself (from memory)
Q1. A composite action is shaped like a…
Q2. To reuse logic that must run several jobs and take secrets, use a…
Q3. This repo triggers one pipeline from another using…
workflow_call here — build dispatches a
repository_dispatch event that the deploy workflow listens for.
.github/actions/…/action.yml, using: composite; uses:
in a step). REUSABLE WORKFLOW = pipeline-shaped (whole JOBS; on: workflow_call;
uses: at job level) — the ONLY one that can fan across jobs, gate on environments,
take workflow-level secrets. RULE: is it shaped like a step or a pipeline? REPO: went almost
all-in on COMPOSITE ACTIONS — 76 of them (auth-oidc, setup-k8s, tool-install, tbd.build-backend,
tbd.deploy-backend, runners, binauthz-sign…). NO reusable workflows — pipeline→pipeline uses
repository_dispatch (build fires an event the deploy listens for). Trade-off:
independent/separately-triggerable pipelines vs typed workflow_call inputs.