Skip to main content
Understanding Reusable Workflows in GitHub Actions
3 min read

Understanding Reusable Workflows in GitHub Actions

CICUBE ANALYTICS INSIGHTS
Engineering Velocity: 25% Team Time Lost to CI Issues
View Platform →
3.5h
Time Saved/Dev/Week
40%
Faster Releases
Click for next insight

Introduction

We wanted to share some thoughts on how we can improve your workflow setup by reusing existing workflows, which could save us time and reduce duplication in our CI processes.

Instead of creating new workflows every time from scratch, we can create reusable workflows that anyone in our organization can then use. In this way, we won't have to copy-paste workflows across repositories because they will be so much easier to maintain. These reusable workflows can contain a number of jobs-deployments in our case-and can be referenced from any other workflow in only a few lines of YAML.

The big win here is that if a reusable workflow exists, is defined, and has been tested, then we can invoke it with ease and speed from other workflows. Such a kind of approach aside from saving development time enforces best practices since all the workflows are standardized. This could be seen in a reusable workflow for deploying to the staging and review, in addition to production, without having to duplicate steps.

Steps we will cover in this article:

How to Create a Reusable Workflow

Below is a simple example of how one might set up a reusable workflow. This workflow takes in an input string and a secret from calling workflows, and uses them in an action:

.github/workflows/reusable-workflow.yml
name: Reusable workflow example

on:
workflow_call:
inputs:
config-path:
required: true
type: string
secrets:
token:
required: true
jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v4
with:
repo-token: ${{ secrets.token }}
configuration-path: ${{ inputs.config-path }}

How to Call a Reusable Workflow

Once the reusable workflow has been created, you would call it from another workflow using the keyword uses. This is one way you might do this:

.github/workflows/call-reusable-workflow.yml
jobs:
call-workflow-passing-data:
uses: cicube-org/cicube-repo/.github/workflows/reusable-workflow.yml@main
with:
config-path: .github/labeler.yml
secrets:
envPAT: ${{ secrets.envPAT }}

Using a Matrix Strategy with Reusable Workflows:

You can also pass different inputs to a reusable workflow by using a matrix strategy, which is pretty useful for running variants of jobs. The following example shows using a matrix strategy for variables of dev, stage, and prod:

.github/workflows/matrix-reusable-workflow.yml
jobs:
ReuseableMatrixJobForDeployment:
strategy:
matrix:
target: [dev, stage, prod]
uses: cicube/cicube-repo/.github/workflows/deployment.yml@main
with:
target: ${{ matrix.target }}

Good to Know

  • You can call up to 20 reusable workflows from a single workflow file.
  • Reusable workflows can be nested up to four levels deep.
  • Environment variables do not pass between caller and called workflows automatically. Use outputs instead of environment variables.

Conclusion

Reusing workflows via GitHub Actions creates consistency amongst our pipelines and reduces friction when updating our CI pipelines. Less duplication wastes less time, and iterating on already-tested workflows further streamlines the processes after some time and makes these easier to manage, saving time and boosting quality across all of our workflows.