CI/CD Fundamentals · Module 11 of 12

Reusable workflows, governance and troubleshooting

Reduce pipeline duplication, pin external dependencies deliberately and troubleshoot from run context before rerunning blindly.

Learning objectives

By the end of this module, you should be able to:

  • Recognize when a reusable workflow is appropriate.
  • Explain why immutable action references improve supply-chain control.
  • Use logs, inputs, permissions and event context to troubleshoot failed runs.

Reuse policy, not accidental complexity

Reusable workflows can centralize common build or deployment contracts. Keep interfaces explicit so callers know required inputs, outputs, secrets and permissions.

External actions are dependencies

Third-party and even first-party actions execute code in the workflow. GitHub's secure-use guidance recommends pinning actions to a full-length commit SHA for immutable references when strong supply-chain control is required.

Troubleshoot evidence before retrying

Check the event payload, job permissions, runner environment, resolved inputs, logs and artifact state. A rerun without understanding can reproduce or conceal the same fault.

Worked examples

See the idea in practice.

Reusable workflow call shape

jobs:
  build:
    uses: ./.github/workflows/reusable-build.yml
    with:
      runtime: '22'
  • A local reusable workflow can establish a shared build contract.
  • Inputs should be typed and documented in the called workflow.
Hands-on lab

Lab — Centralize a reusable local build contract

Goal: Create one build script invoked by two service pipelines and prove behavior changes in one place.

STEP 1

Create reusable function

mkdir -p ~/gnu-cicd-labs/module11/{service-a,service-b} && cd ~/gnu-cicd-labs/module11
cat > reusable-build.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
service="$1"
test -f "$service/source.txt"
mkdir -p "$service/dist"
tr '[:lower:]' '[:upper:]' < "$service/source.txt" > "$service/dist/app.txt"
EOF
chmod +x reusable-build.sh
STEP 2

Create two callers

printf 'alpha\n' > service-a/source.txt
printf 'beta\n' > service-b/source.txt
STEP 3

Invoke shared build contract

./reusable-build.sh service-a
./reusable-build.sh service-b
STEP 4

Verify outputs

grep -q ALPHA service-a/dist/app.txt && grep -q BETA service-b/dist/app.txt

Verify

  • Both services use the same build implementation.
  • The shared contract fails if the required source file is missing.

Expected outcome

  • One reusable component provides consistent behavior across callers.

If it fails

  • Keep reusable interfaces small; excessive conditional logic can make a shared workflow harder to understand than duplication.
  • In Actions, inspect permissions in both caller and called workflow when authentication fails.
Real-world connection

Platform teams use reusable workflow contracts to standardize builds and deployments while letting application repositories retain clear inputs.

Avoid these traps

Common mistakes

  • Copy-pasting the same deployment workflow into dozens of repositories.
  • Treating external actions as trusted without dependency controls.
  • Rerunning a failure without checking event, permissions or logs.
Knowledge check

Can you explain it without looking back?

Open each answer only after you have tried to answer the question yourself.

1What should a reusable workflow expose clearly?

Its inputs, outputs, required secrets/permissions and expected behavior.

2Why pin an action to a full commit SHA in high-assurance workflows?

It gives an immutable action reference and reduces risk from a movable tag being changed.

3What should you inspect before blindly rerunning a failed workflow?

The trigger/event, inputs, permissions, runner context, logs and artifacts associated with the failure.

My Learning

Record your progress for this module.

Progress is saved in this browser immediately. When you sign in to My Learning, it can also sync across devices.

Not started

Attempt the core lab and knowledge checks before marking the module complete.