Reusable Workflows & Composite Actions
IntermediateReusable workflows let you define a pipeline once and call it from multiple repos. Composite actions bundle multiple steps into a single reusable unit — eliminating duplication across workflows.
Overview
As your GitHub Actions usage grows, duplication is the biggest problem: every repo has a slightly different Docker build job, every team re-implements the same test setup. GitHub provides two reuse mechanisms: Reusable Workflows (call-workflow) for entire jobs or job sequences — used when you want to standardise the full pipeline across repos. Composite Actions for sharing a sequence of steps within a single job — used when you have a common setup sequence (configure AWS, set up Node, restore cache) that appears in many places. Organisation-level standardisation with reusable workflows is how platform engineering teams enforce consistent CI/CD practices.
Reusable Workflows
A workflow becomes reusable by adding workflow_call to its triggers. Caller workflows invoke it with uses: instead of normal job steps.
# ── REUSABLE WORKFLOW: .github/workflows/build-and-push.yml ──────────────────
# (can be in the same repo or a shared .github repo)
name: Build and Push Docker Image (Reusable)
on:
workflow_call: # makes this workflow callable
inputs:
image-name:
required: true
type: string
environment:
required: false
type: string
default: staging
secrets:
registry-token:
required: true
outputs:
image-digest:
description: "SHA256 digest of the pushed image"
value: ${{ jobs.build.outputs.digest }}
jobs:
build:
runs-on: ubuntu-latest
outputs:
digest: ${{ steps.push.outputs.digest }}
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
password: ${{ secrets.registry-token }}
- name: Build and push
id: push
uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/${{ inputs.image-name }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
# ── CALLER WORKFLOW: in any repo ─────────────────────────────────────────────
name: Release
on:
push:
branches: [main]
jobs:
build:
uses: my-org/.github/.github/workflows/build-and-push.yml@main
with:
image-name: my-org/my-app
environment: production
secrets:
registry-token: ${{ secrets.GITHUB_TOKEN }}
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- run: echo "Deployed image digest: ${{ needs.build.outputs.image-digest }}"Composite Actions
Composite actions bundle multiple steps into a single action.yml file. They live in a repo under .github/actions/ and are referenced with uses: ./path/to/action or uses: org/repo/path@ref.
# .github/actions/setup-node-project/action.yml
name: Setup Node Project
description: Checkout, setup Node, restore cache, install deps
inputs:
node-version:
description: Node.js version
default: '20'
working-directory:
description: Project directory
default: '.'
outputs:
cache-hit:
description: Whether node_modules cache was hit
value: ${{ steps.cache.outputs.cache-hit }}
runs:
using: composite # composite = multiple steps
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
- name: Restore cache
id: cache
uses: actions/cache@v4
with:
path: ${{ inputs.working-directory }}/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
- name: Install dependencies
if: steps.cache.outputs.cache-hit != 'true'
shell: bash
working-directory: ${{ inputs.working-directory }}
run: npm ci
# Use the composite action in any workflow:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: ./.github/actions/setup-node-project # local reference
with:
node-version: '20'
- run: npm test
lint:
runs-on: ubuntu-latest
steps:
- uses: ./.github/actions/setup-node-project
- run: npm run lintSelf-Hosted Runners
GitHub-hosted runners are ephemeral VMs. Self-hosted runners run on your own infrastructure — necessary for private network access, GPU workloads, or specific hardware. Scale them with Actions Runner Controller (ARC) on Kubernetes.
# When to use self-hosted runners:
# - Need access to private network (internal databases, private registries)
# - Need specific hardware (GPU for ML, large RAM, fast NVMe)
# - Cost at scale (GitHub-hosted is ~$0.008/minute; self-hosted is free)
# - Compliance: code must not leave your infrastructure
# Register a self-hosted runner (manual, for one machine):
# Settings → Actions → Runners → New self-hosted runner
# Follow the curl+configure+run instructions on your machine
# Actions Runner Controller (ARC) — Kubernetes-based auto-scaling runners
helm install arc \
--namespace arc-systems \
--create-namespace \
oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller
helm install arc-runner-set \
--namespace arc-runners \
--create-namespace \
--set githubConfigUrl=https://github.com/my-org \
--set githubConfigSecret=arc-controller-manager \
oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set
# Use self-hosted runner in workflow:
jobs:
build:
runs-on: self-hosted # any available self-hosted runner
# or with labels:
runs-on: [self-hosted, linux, gpu, high-memory]
# ARC scales runners from 0 to N based on queue depth
# Each runner pod is ephemeral — starts fresh per job (no persistent state)Key Points to Remember
- 1Reusable workflows (workflow_call) share entire job sequences — best for org-wide pipeline standards.
- 2Composite actions share step sequences within a job — best for common setup patterns.
- 3Reusable workflows support inputs, secrets, and outputs — fully parameterisable.
- 4Self-hosted runners are needed for private network access, special hardware, or compliance.
- 5Actions Runner Controller (ARC) auto-scales self-hosted runners on Kubernetes from 0 to N.
- 6Publish composite actions to a dedicated .github repo to share across all org repositories.
Interview Questions
Sign in to ask AriaWhat is the difference between a reusable workflow and a composite action?
Ask Aria about Reusable Workflows & Composite Actions
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.