Code Reference

Reusable Workflows

GitHub Actions · Reference cheat sheet

Reusable Workflows

GitHub Actions · Reference cheat sheet


📋 Overview

Reusable workflows let one workflow call another with workflow_call / uses: org/repo/.github/workflows/file.yml@ref. Share CI patterns across repos while keeping callers thin. Pass inputs, secrets, and read outputs from called jobs.

🔧 Core concepts

PieceRole
on.workflow_callDefine a callable workflow
inputs / secretsContract for callers
uses: ./.github/workflows/x.ymlSame-repo call
uses: org/repo/...@v1Cross-repo call
with: / secrets:Pass values
jobs.*.outputsReturn data to caller

Called workflows run as jobs from the caller’s perspective (needs works). Nesting depth and some features (e.g. certain matrix cases) have limits.

💡 Examples

Callee (_ci.yml):

name: Reusable CI
on:
  workflow_call:
    inputs:
      node-version:
        type: string
        default: '22'
    secrets:
      NPM_TOKEN:
        required: false

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
      - run: npm ci
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
      - run: npm test

Caller:

jobs:
  call-ci:
    uses: ./.github/workflows/_ci.yml
    with:
      node-version: '20'
    secrets:
      NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

⚠️ Pitfalls

  • Caller must explicitly pass secrets—secrets: inherit only when appropriate.
  • Version-pin @ref for cross-repo reuse; floating branches can break you.
  • Not everything is supported inside reusable workflows (check current limits).
  • Debugging spans two files—add clear job names.
  • Permissions are evaluated carefully across caller/callee—set both as needed.
  • Avoid deep nesting; prefer one reusable layer.

On this page