Reusable Workflows and Composite Actions in GitHub Actions

A
Author
01 Jul, 2026 1 min read 366 views

When ten repositories have nearly identical CI files, every improvement must be made ten times. GitHub Actions offers two ways to share.

Composite actions: share a group of steps

# .github/actions/setup-app/action.yml
name: Set up app
description: Install Node, restore cache and install dependencies
inputs:
  node-version:
    default: '22'
runs:
  using: composite
  steps:
    - uses: actions/setup-node@v4
      with:
        node-version: ${{ inputs.node-version }}
        cache: npm
    - run: npm ci
      shell: bash
steps:
  - uses: actions/checkout@v4
  - uses: ./.github/actions/setup-app
  - run: npm test

Reusable workflows: share whole jobs

# In acme/ci-templates: .github/workflows/node-ci.yml
name: Node 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 }}
          cache: npm
      - run: npm ci
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
      - run: npm test
# In each app repository
jobs:
  ci:
    uses: acme/ci-templates/.github/workflows/node-ci.yml@v1
    with:
      node-version: '22'
    secrets: inherit

Which one?

  • Composite action: a few steps reused inside your own jobs (setup, build, notify).
  • Reusable workflow: a complete pipeline with its own jobs, runners and environments, standardised across many repositories.

Version shared workflows with tags (@v1) so a change to the template doesn't break every repository at once.

Was this article helpful?

Comments

No comments yet. Have a question or a tip? Be the first to share it.

Leave a comment

Comments are reviewed before they appear.