Reusable Workflows and Actions
Create and leverage reusable workflows and custom actions to modularize your pipelines and promote consistency across repositories.
Reusable Workflows and Actions is a free DevOps Bootcamp lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the DevOps Bootcamp learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Introduction to Workflow Reusability
In modern software development, efficiency and consistency are key. As your projects grow, so do your automation needs.
Reusable workflows and custom actions in GitHub Actions help you avoid repeating yourself, making your CI/CD pipelines more maintainable and robust.
Why Reuse Workflows?
Imagine having multiple applications that all need the same build, test, or deployment steps. Copy-pasting workflow code leads to:
- Duplication: More code to maintain.
- Inconsistency: Easy to miss updates across workflows.
- Maintenance headaches: Changes require updating many files.
Reusability solves these problems!
Defining a Reusable Workflow
A reusable workflow is a complete workflow that can be called by other workflows. It's stored in your repository and acts like a template.
To make a workflow reusable, you use the workflow_call event. This tells GitHub Actions that this workflow is meant to be called, not triggered by typical events like push or pull_request.
Reusable Workflow Example
Here's a simple reusable workflow that simulates a build. Save this in .github/workflows/reusable-build.yml.
It defines an output called build_id that calling workflows can use.
name: Reusable Build Component
on:
workflow_call:
outputs:
build_id:
description: "The ID of the build operation"
value: ${{ jobs.build.outputs.build_id }}
jobs:
build:
runs-on: ubuntu-latest
outputs:
build_id: ${{ steps.generate_id.outputs.id }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Generate build ID
id: generate_id
run: echo "id=$(date +%s)" >> "$GITHUB_OUTPUT"
- name: Simulate build
run: echo "Building project with ID ${{ steps.generate_id.outputs.id }}..."
Calling a Reusable Workflow
To use a reusable workflow, another workflow (the 'caller') uses the uses keyword, similar to how you'd use a GitHub Action.
You specify the path to the reusable workflow file within your repository, or even from another repository or a specific version.
Caller Workflow Example
This workflow, saved as .github/workflows/main-app-ci.yml, calls our reusable-build.yml workflow.
Notice how it accesses the build_id output from the called workflow using jobs.call-build.outputs.build_id.
name: Main App CI
on: [push]
jobs:
call-build:
uses: ./.github/workflows/reusable-build.yml
outputs:
build_id: ${{ jobs.call-build.outputs.build_id }}
deploy:
needs: call-build
runs-on: ubuntu-latest
steps:
- name: Deploy app
run: echo "Deploying app built with ID ${{ needs.call-build.outputs.build_id }}"
Passing Inputs to Reusable Workflows
Reusable workflows aren't just static templates; they can accept inputs, making them highly flexible.
You define expected inputs in the on: workflow_call: inputs: section of the reusable workflow, specifying their type, whether they are required, and a description. The calling workflow passes these inputs using the with: keyword.
Reusable Workflow with Inputs
Here's an updated reusable-build.yml that accepts a target_env input. This allows the same build logic to be customized for different environments.
name: Reusable Build Component with Input
on:
workflow_call:
inputs:
target_env:
required: true
type: string
description: "The target environment for the build"
outputs:
build_id:
description: "The ID of the build operation"
value: ${{ jobs.build.outputs.build_id }}
jobs:
build:
runs-on: ubuntu-latest
outputs:
build_id: ${{ steps.generate_id.outputs.id }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Generate build ID
id: generate_id
run: echo "id=$(date +%s)" >> "$GITHUB_OUTPUT"
- name: Simulate build for ${{ inputs.target_env }}
run: echo "Building project for ${{ inputs.target_env }} with ID ${{ steps.generate_id.outputs.id }}..."
Calling with Inputs Example
Now, our main CI workflow can call the reusable build component twice, once for 'staging' and once for 'production', passing different target_env values.
name: Main App CI with Input
on: [push]
jobs:
call-build-staging:
uses: ./.github/workflows/reusable-build-with-input.yml
with:
target_env: 'staging'
outputs:
build_id: ${{ jobs.call-build-staging.outputs.build_id }}
call-build-prod:
uses: ./.github/workflows/reusable-build-with-input.yml
with:
target_env: 'production'
outputs:
build_id: ${{ jobs.call-build-prod.outputs.build_id }}
Reusable Workflows vs. Custom Actions
While both promote reusability, they serve different purposes:
- Reusable Workflows: Orchestrate a series of jobs. They define a complete workflow structure (e.g., build, test, deploy).
- Custom Actions: Perform a specific, single task within a job (e.g., set up Node.js, publish a package). They are the building blocks *inside* a job's steps.
Think of workflows as recipes and actions as individual ingredients or steps.
Quick Check
Which of the following are key benefits of using reusable workflows in GitHub Actions?
Recap: Reusable Workflows & Actions
We've explored how reusable workflows help modularize your CI/CD pipelines.
- They are defined using
workflow_call. - They can accept
inputsand provideoutputs. - Calling workflows use the
useskeyword. - They differ from custom actions, which are single-task building blocks within jobs.
Embracing reusability leads to more efficient, consistent, and maintainable automation across your projects.
Frequently asked questions
Is the “Reusable Workflows and Actions” lesson free?
Yes — the full text of “Reusable Workflows and Actions” is free to read here on the web, and the DevOps Bootcamp course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the DevOps Bootcamp course, upgrade to CoddyKit PRO.
What will I learn in “Reusable Workflows and Actions”?
Create and leverage reusable workflows and custom actions to modularize your pipelines and promote consistency across repositories. You practise DevOps Bootcamp with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start DevOps Bootcamp?
No prior experience is required. DevOps Bootcamp on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Reusable Workflows and Actions” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this DevOps Bootcamp lesson?
Yes. Every DevOps Bootcamp lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Matrix Builds for Multiple Environments
- Caching Dependencies for Speed
- Reusable Workflows and Actions
- Conditional Execution and Job Dependencies