</>

Technology

GitHub Actions

Difficulty

Intermediate

Interview Question

What are reusable workflows in GitHub Actions? How do you create and call them?

Answer

Reusable Workflows in GitHub Actions

Reusable workflows are workflow files that can be called from other workflows — the DRY principle for GitHub Actions. One team defines the standard pipeline; all projects reuse it.

Creating a Reusable Workflow

YAML
# .github/workflows/run-tests.yml  (in your repo or a shared org repo)
name: Reusable  Run Automation Tests

on:
  workflow_call:             # ← this makes it reusable
    inputs:
      environment:
        description: 'Target environment'
        required: true
        type: string
      browser:
        description: 'Browser'
        required: false
        type: string
        default: 'chrome'
      java-version:
        required: false
        type: string
        default: '17'

    secrets:
      DB_PASSWORD:
        required: true
      API_KEY:
        required: false

    outputs:
      test-result:
        description: 'Pass or Fail'
        value: ${{ jobs.test.outputs.result }}

jobs:
  test:
    runs-on: ubuntu-latest
    outputs:
      result: ${{ steps.run.outcome }}

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-java@v4
        with:
          java-version: ${{ inputs.java-version }}
          distribution: temurin
          cache: maven

      - id: run
        name: Run Tests
        run: mvn test -Denv=${{ inputs.environment }} -Dbrowser=${{ inputs.browser }}
        env:
          DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
          API_KEY:     ${{ secrets.API_KEY }}

      - if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-results-${{ inputs.environment }}
          path: target/surefire-reports/

Calling the Reusable Workflow

YAML
# .github/workflows/ci.yml  (in any project repo)
name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  smoke-tests:
    uses: my-org/shared-workflows/.github/workflows/run-tests.yml@main
    with:
      environment: staging
      browser:     chrome
    secrets:
      DB_PASSWORD: ${{ secrets.STAGING_DB_PASSWORD }}
      API_KEY:     ${{ secrets.STAGING_API_KEY }}

  regression-tests:
    uses: my-org/shared-workflows/.github/workflows/run-tests.yml@main
    with:
      environment: qa
      browser:     firefox
    secrets:
      DB_PASSWORD: ${{ secrets.QA_DB_PASSWORD }}
      API_KEY:     ${{ secrets.QA_API_KEY }}

  use-output:
    needs: smoke-tests
    runs-on: ubuntu-latest
    steps:
      - run: echo "Smoke test result: ${{ needs.smoke-tests.outputs.test-result }}"

Reusable Workflow vs Composite Action

Reusable WorkflowComposite Action
File location.github/workflows/action.yml in any directory
ContainsFull workflow (jobs + steps)Only steps
Runs onIts own runnerCaller's runner
Called viauses: org/repo/.github/workflows/file.yml@refuses: org/repo/path@ref
Can use secretsYesNo (must pass as input)
Best forFull pipelinesSmall reusable step groups

Secrets Inheritance (inherit keyword)

YAML
# Pass ALL calling workflow's secrets automatically
jobs:
  call-workflow:
    uses: org/repo/.github/workflows/deploy.yml@main
    secrets: inherit    # ← passes all secrets from caller
    with:
      environment: production

Follow AutomateQA

Related Topics