GitHub Actions Certification
Reusable Workflows and Reporting
Understanding Reusable Workflows
By centralizing common jobs—like deployment—into standalone workflows, you can reduce duplication, simplify updates, and enforce best practices across all your repositories. This guide shows you how to extract deployment logic into a reusable workflow and invoke it from language-specific CI pipelines.
Sample CI Workflow for a Node.js App
Here’s an example .github/workflows/ci-testing.yml
that runs tests, coverage, dependency scanning, build, and deployments in sequence:
name: CI Workflow
on: push
jobs:
unit-tests:
runs-on: ubuntu-latest
strategy:
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: npm install
- name: Run unit tests
run: npm test
code-coverage:
needs: unit-tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Generate coverage report
run: npm run coverage
dependency-scan:
needs: code-coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Scan for vulnerabilities
run: npm audit
build:
needs: dependency-scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build application
run: npm run build
deploy-dev:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Authenticate to DEV
run: echo "Authenticating to DEV"
- name: Deploy to development
run: echo "Deploying to development environment"
- name: Notify team
run: echo "Development deployment complete"
deploy-prod:
needs: deploy-dev
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Authenticate to PROD
run: echo "Authenticating to PROD"
- name: Deploy to production
run: echo "Deploying to production environment"
- name: Notify team
run: echo "Production deployment complete"
Warning
Copy-pasting deployment steps across multiple workflows leads to fragmented updates and higher maintenance costs. A single change requires edits in every file.
Why Use Reusable Workflows?
A reusable workflow is a YAML file that other workflows can invoke via workflow_call
. Benefits include:
Benefit | Description |
---|---|
Avoid duplication | Define deployment logic once and reuse everywhere. |
Simplify maintenance | Update a single file to apply changes organization-wide. |
Enforce standards | Share audited, best-practice workflows across teams. |
Example Repository Layout
Assume the following structure in your XYZ/nodejs-app-repo
:
.github/workflows/awesome-app.yaml
.github/workflows/reusable-workflow.yaml
Original Workflow: awesome-app.yaml
This caller workflow builds the app, runs tests, and then invokes the reusable deployment job:
name: My Awesome App
on: push
jobs:
unit-testing:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: npm test
code-coverage:
needs: unit-testing
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: npm run coverage
build:
needs: code-coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: npm run build
dev-deploy:
needs: build
uses: ./.github/workflows/reusable-workflow.yaml
with:
environment: development
secrets:
DEPLOY_TOKEN: ${{ secrets.DEV_DEPLOY_TOKEN }}
Reusable Workflow: reusable-workflow.yaml
By declaring on.workflow_call
, you expose inputs, secrets, and jobs that any caller workflow can use:
name: Reusable Deployment
on:
workflow_call:
inputs:
environment:
type: string
required: true
secrets:
DEPLOY_TOKEN:
required: true
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Authenticate with cloud
run: echo "Authenticating for ${{ inputs.environment }} using ${{ secrets.DEPLOY_TOKEN }}"
- name: Deploy to ${{ inputs.environment }}
run: echo "Deploying to ${{ inputs.environment }} environment"
- name: Notify team
run: echo "${{ inputs.environment }} deployment complete"
Invoking the Reusable Workflow
You can call this reusable workflow from any repository or branch:
dev-deploy:
needs: build
uses: ./.github/workflows/reusable-workflow.yaml
with:
environment: development
secrets:
DEPLOY_TOKEN: ${{ secrets.DEV_DEPLOY_TOKEN }}
prod-deploy:
needs: dev-deploy
uses: ./.github/workflows/reusable-workflow.yaml
with:
environment: production
secrets:
DEPLOY_TOKEN: ${{ secrets.PROD_DEPLOY_TOKEN }}
Note
Inputs and secrets are strongly typed. Ensure that every workflow_call
declaration and invocation matches the expected names and types.
Key Terminology
- Caller workflow: The YAML file that uses
uses:
to invoke a reusable workflow. - Called workflow: The reusable workflow that declares
on.workflow_call
.
Links and References
Watch Video
Watch video content