Skip to main content
RunBook Academy

Git, CI/CD & GitOpsXLVII · Pipeline DependenciesComposition

Pipeline triggers and chains — workflow_run and workflow_call

Intermediate⏱ ~20 mingit

What you'll learn

  • Distinguish intra-workflow `needs:` from inter-workflow triggers
  • Declare a chain with `on.workflow_run` and filter by branch or outcome
  • Declare a callable with `on.workflow_call` and pass inputs and secrets
  • Recognise the security implications of cross-workflow triggers

Prerequisites

Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x

Not yet marked complete on this device.

Intra-workflow needs: declares edges between jobs in the same workflow file. Inter-workflow chains declare edges between workflows. Two mechanisms matter: on.workflow_run and on.workflow_call. One graph, two mechanisms.

workflow_run: chain after another workflow

on.workflow_run fires when another workflow completes.

on:
  workflow_run:
    workflows: ["ci"]
    types: [completed]
    branches: [main]

Fires after ci completes on main. Receives github.event.workflow_run; default waits for the upstream’s final job.

workflow_call: call as a reusable step

on.workflow_call makes a workflow callable via uses:.

on:
  workflow_call:
    inputs:
      environment:
        required: true
        type: string
    secrets:
      deploy_key:
        required: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: ${ inputs.environment }
    steps:
      - run: deploy.sh
        env:
          DEPLOY_KEY: ${ secrets.deploy_key }

Caller:

jobs:
  release:
    uses: ./.github/workflows/deploy.yml
    with:
      environment: production
    secrets:
      deploy_key: ${ secrets.DEPLOY_KEY }

The called workflow runs in the caller’s context.

Inter-workflow versus intra-workflow

flowchart LR
    subgraph W1["ci.yml"]
        B["build"] --> T["test"]
        T --> D["deploy"]
    end
    W1 -->|workflow_run| W2["notify.yml"]
  • needs: orders jobs in one file.
  • workflow_run orders workflows across files.
  • workflow_call makes a workflow a step in another.

Filter chains deliberately

on:
  workflow_run:
    workflows: ["ci"]
    types: [completed]
    branches: [main, release/*]

branches: uses the same glob as on.push.branches. types: selects completed / requested / in_progress; only completed matters.

Production discipline

  1. workflow_run cross-file; needs: in-file.
  2. Filter workflow_run by branch and outcome.
  3. Pass secrets to workflow_call explicitly.
  4. Document the cross-file DAG.

Cross-course references

  • Ansible for Production Sysadmins - Part XXXVII uses the same composition in AWX.
  • Linux for Production Sysadmins - Part XXX uses systemd timers.

Quiz

Knowledge check · 4 questions

  1. Q1. Workflow A has `on.workflow_run: workflows: [ci]`. When does A start?

  2. Q2. A reusable workflow invoked via `uses: ./.github/workflows/deploy.yml` inherits all secrets of the calling workflow automatically.

  3. Q3. Name the two inter-workflow chain mechanisms in GitHub Actions and identify which one is synchronous (in-line) versus asynchronous (separate run).

  4. Q4. Diagnose why a notification workflow runs even when CI failed, and recommend the fix.

    Team M: `ci.yml` has build, test, deploy. `notify.yml` has `on.workflow_run: workflows: [ci]`. Notify fires on every completion, including failures.

Passing score: 75%. Answers are checked in this browser.