Day 45advancedMar 17, 2026

Build Reusable Steps with Composite Actions

Composite actions turn repetitive multi-step setup blocks into a single reusable uses: line.

cicdgithub-actionsreusability
Share:

What

Composite actions bundle multiple workflow steps into a single reusable action. Unlike reusable workflows which are entire jobs, composite actions are individual steps you can mix into any job. You define them in an action.yml file with using: composite, and they can accept inputs, run shell commands, and even call other actions.

Why It Matters

Every project has boilerplate setup steps β€” install dependencies, configure caching, set environment variables. Without composite actions, you copy these 5-10 lines into every workflow. Composite actions encapsulate that setup into a single uses: line, making workflows shorter, more readable, and easier to maintain.

Example

# .github/actions/setup-node-env/action.yml
name: 'Setup Node Environment'
description: 'Install Node.js, cache dependencies, and install packages'
inputs:
  node-version:
    description: 'Node.js version'
    required: false
    default: '20'
runs:
  using: composite
  steps:
    - uses: actions/setup-node@v4
      with:
        node-version: ${{ inputs.node-version }}
        cache: 'npm'
    - name: Install dependencies
      run: npm ci
      shell: bash
    - name: Verify installation
      run: node --version && npm --version
      shell: bash

# Usage in any workflow:
# .github/workflows/ci.yml
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: ./.github/actions/setup-node-env
        with:
          node-version: '20'
      - run: npm test
yaml

Common Mistake

Confusing composite actions with reusable workflows. Composite actions run as steps within a job and share the same runner. Reusable workflows run as separate jobs on their own runners. Use composite actions for shared setup steps, and reusable workflows for shared entire pipelines.

Quick Fix

Remember: if you need to share steps, use a composite action. If you need to share an entire job or pipeline, use a reusable workflow. And always specify shell: bash in composite action run steps β€” it's required.

Key Takeaways

  • 1Composite actions bundle multiple steps into one reusable action
  • 2Define with using: composite in action.yml
  • 3Accept inputs for customization, just like regular actions
  • 4Must specify shell: bash for every run step
  • 5Composite = shared steps, Reusable workflow = shared jobs

Was this tip helpful?

Help us improve the DevOpsPath daily collection

Share: