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 actionReusable workflow
Shaped likea step (a sequence of steps)a pipeline (whole jobs)
Lives in.github/actions/<name>/action.yml.github/workflows/<name>.yml
Invoked byuses: in a stepuses: at the job level
Needsusing: compositeon: workflow_call
Can it run multiple jobs / gate on environments / take secrets?no — it's steps in one jobyes — it's a full pipeline
The rule of thumb Is the reused thing shaped like a step or a pipeline? "Authenticate to GCP," "install skaffold," "build the image" are steps → composite action. "Run the whole build-scan-sign flow across jobs with secrets and gates" is a pipeline → reusable workflow. If it must fan across jobs or consume secrets at the workflow level, only a reusable workflow can express it.1

How this repo does it — composite actions + repository_dispatch

Anchor — 76 composite actions, zero reusable workflows This repo went almost entirely with composite actions.github/actions/ holds 76 of them. A workflow's jobs are thin; the real work is in shared actions: Crucially, there are no reusable workflows (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.
Why this is a defensible choice 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.
Read this next

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…

Composite = reusable steps in one job. A reusable workflow is the pipeline-shaped option.

Q2. To reuse logic that must run several jobs and take secrets, use a…

Only a reusable workflow can fan across jobs, gate on environments, and consume secrets. Composite actions are one-job step sequences.

Q3. This repo triggers one pipeline from another using…

No workflow_call here — build dispatches a repository_dispatch event that the deploy workflow listens for.
Composite action vs reusable workflow — and this repo's choice.
recall, then click to reveal
Two DRY mechanisms: COMPOSITE ACTION = step-shaped (reusable STEPS in one job; .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.
✅ Part 1 complete You have the fundamentals: CI vs CD and this repo's real ship chain (L1), the GitHub Actions hierarchy (L2), the CI gate + its router (L3), and the two reuse mechanisms (L4). Part 2 follows the artifact out the door: building & pushing the image, the trunk-based deploy, self-hosted ARC runners, and the deploy mechanism.
Ready for Part 2 (build, deploy & trunk-based delivery)? Or a mock interview on Part 1 — "reusable workflow vs composite action" is a classic. Ask me.

1. GitHub — Reusable workflows; Create a composite action.