Streamline Your DevOps with GitHub reusable workflows and GitHub Actions

Incredibuild logo

Incredibuild Team

reading time: 

10 minutes

In today’s DevOps landscape, automation is key to development teams being able to deliver features faster and maintain high-quality codebases. This is where a tool like GitHub Actions has become indispensable, as it empowers you to automate, customize, and execute GitHub workflows right in your repositories. 

Of course, as projects scale and the number of repositories multiplies, maintaining consistent and efficient workflows across all of them becomes a significant challenge. This is where GitHub reusable workflows come into the picture, transforming how we approach CI/CD pipelines.

Reusable workflows offer a way to optimize, standardize, and scale our processes effortlessly across multiple projects. By encapsulating common workflows into reusable templates, we can reduce redundancy, minimize errors, and ensure that best practices are followed throughout our organization.

This blog post will explore GitHub reusable workflows, their benefits, and how to build and integrate them into your development process. Whether managing a handful of repositories or overseeing a vast array of projects, learning to create reusable workflows in GitHub Actions can be a game-changer for your team’s productivity and code quality.

Understanding GitHub reusable workflows

GitHub reusable workflows are YAML-defined workflows that can be shared and invoked across multiple repositories. They encapsulate a set of jobs and steps—such as testing, building, or deploying—into a single, reusable file. This approach allows teams to maintain consistency and reduce duplication by referencing the same workflow in different projects.

Why use reusable workflows?

In environments where multiple repositories have similar CI/CD needs, GitHub Actions reusable workflows eliminate the redundancy of duplicating workflow code. By defining a workflow once and referencing it elsewhere, updates and changes propagate automatically to all dependent repositories. 

This cuts down repetitive tasks and ensures a uniform approach, which is especially valuable for organizations aiming to enforce consistent standards across numerous repositories.

How do GitHub reusable workflows work?

Reusable workflows leverage the workflow_call event, allowing one GitHub workflow to trigger another. This mechanism enables workflows to accept inputs and provide outputs, in the same way as a callable function. Unlike standalone actions that perform single tasks, reusable workflows can encompass entire pipelines and integrate seamlessly with GitHub’s YAML configurations, providing a flexible and modular approach to workflow management.

Key benefits of reusable workflows

Using GitHub Actions reusable workflows brings a few key advantages that enhance your CI/CD pipelines.

Efficiency 

They eliminate the need to duplicate GitHub workflows across projects, saving time and reducing redundancy. By standardizing tasks like testing and deployment, teams can focus more on development rather than repetitive configuration.

Improved maintenance

Centralizing workflow logic simplifies updates and bug fixes. Changes made to a GitHub reusable workflow automatically apply to all dependent projects, ensuring consistency and reducing the effort required for maintenance.

Scalability and flexibility

Reusable workflows in GitHub support scalability by allowing customization for specific project needs while maintaining a consistent base structure. This flexibility makes it easy to adopt standardized workflows as new projects are added.

Enhanced collaboration

Consistent workflows facilitate better team collaboration and streamline onboarding. They effectively reduce the learning curve for new team members, helping them integrate into projects more efficiently.

Limitations and considerations of reusable workflows

While GitHub reusable workflows offer significant benefits, they also have limitations to consider.

Configuration complexity

Configuring reusable workflows for different environments can be complex. Limitations in handling environment variables and secrets require careful planning to ensure workflows function correctly across various projects.

Dependency management

Managing dependencies across GitHub workflows is crucial, especially in complex setups. Without proper strategies, conflicts may arise, leading to execution failures. Implementing effective dependency resolution is essential for smooth workflow operations.

Versioning challenges

Maintaining stability requires proper version control of reusable workflows. Without this, updates can unintentionally disrupt dependent workflows. Specific tags or commit hashes help control the version used, ensuring predictability and stability.

Building a reusable workflow in GitHub Actions: Step-by-step guide

Now, let’s walk through how to create a reusable workflow in GitHub Actions.

Creating a basic workflow

You’ll first need to create a standard GitHub workflow in your repository. So, head on over to the .github/workflows/ directory and create a new YAML file with the name ci-pipeline.yml:

name: CI Pipeline

on:

  push:

    branches: [ main ]

jobs:

  build:

    runs-on: ubuntu-latest

    steps:

      – name: Checkout code

        uses: actions/checkout@v3

      – name: Set up Node.js

        uses: actions/setup-node@v3

        with:

          node-version: ’14’

      – name: Install dependencies

        run: npm install

      – name: Run tests

        run: npm test

This basic workflow runs on every push to the main branch, performing code checkouts, setting up Node.js, installing dependencies, and running tests.

Adding environment variables and secrets

You can add environment variables and secrets to make your workflow more dynamic. Environment variables are defined in the env section, while secrets are stored securely in your repository or organization settings:

env:

  NODE_ENV: production

jobs:

  build:

    steps:

      – name: Deploy

        env:

          API_KEY: ${{ secrets.API_KEY }}

        run: npm run deploy

In this snippet, the current environment for the Node.js application is production, while the API key will be retrieved from the repository’s secrets. Remember that secrets are not exposed in logs or outputs, ensuring sensitive data remains secure.

Transforming a standard workflow into a reusable workflow

To convert your workflow into a GitHub Action reusable workflow, modify the on section to use the workflow_call and define any inputs your workflow requires.

name: CI Pipeline

on:

  workflow_call:

    inputs:

      node-version:

        description: ‘Node.js version’

        required: true

        type: string

      run-tests:

        description: ‘Flag to run tests’

        required: false

        type: boolean

        default: true

jobs:

  build:

    runs-on: ubuntu-latest

    steps:

      – name: Checkout code

        uses: actions/checkout@v3

      – name: Set up Node.js

        uses: actions/setup-node@v3

        with:

          node-version: ${{ inputs[‘node-version’] }}

      – name: Install dependencies

        run: npm install

      – name: Run tests

        if: ${{ inputs[‘run-tests’] }}

        run: npm test

By introducing inputs, you enable any workflow that calls this reusable workflow to easily tailor its operations. In this example, node-version and run-tests are inputs that control the Node.js version and whether tests should be run.

Using workflow_call to enable reusability

In the call-workflow section, you’ll specify the reusable workflow with the uses keyword and provide its required inputs. By doing this, you trigger the reusable workflow to run with your chosen parameters, effectively tailoring its execution to the needs of your current project:

name: Use Reusable Workflow

on:

  push:

    branches: [ main ]

jobs:

  call-workflow:

    uses: your-org/your-repo/.github/workflows/ci-pipeline.yml@v1

    with:

      node-version: ’16’

      run-tests: false

Here, we specify node-version as 16 and set run-tests to false, illustrating how you can adjust the workflow’s environment and behavior for your project’s current priorities—whether it’s updating the runtime or temporarily skipping tests to accelerate feedback.

Testing and validating reusable workflows

Before rolling out your reusable workflow across multiple projects, it’s essential to test it thoroughly. So, after creating a test repository to invoke the workflow with various inputs and scenarios, verify that:

  • Inputs are handled correctly
  • Steps execute as expected
  • Secrets and environment variables are accessed properly
  • Edge cases and error conditions are managed gracefully

Additionally, consider implementing automated tests for your reusable workflows. While testing GitHub workflows can be challenging, you can use tools like act to run workflows locally or set up a CI pipeline to validate changes to your workflows.

Investing time in testing ensures that your reusable workflows are robust and reliable, reducing the likelihood of issues when other projects adopt them.

Comparison: Reusable workflows vs. custom actions vs. composite actions

Understanding the differences between reusable workflows, custom actions, and composite actions will help you choose the right tool for your needs.

FeatureReusable workflowsCustom actionsComposite actions
DefinitionFull workflows that can be called by other workflows, including jobs and stepsIndividual units of code packaged for reuse, typically in JavaScript or DockerMultiple actions combined into one action, defined in YAML
StrengthsEncapsulates entire workflows, supports multiple jobs, and maintains consistency across repositoriesHighly customizable, can perform complex tasks, and supports any language/runtimeSimplifies complex workflows by combining steps, easy to create and maintain
LimitationsCan be complex to manage, limited in handling secrets and environment variables across repositoriesRequires more setup and maintenance, may need to manage dependencies manuallyLimited to combining existing actions, less flexible than custom actions
Best use casesStandardizing CI/CD pipelines across multiple projectsWhen you need reusable components with custom logicSimplifying repetitive tasks within workflows

Streamlining GitHub reusable workflows with Incredibuild

Incredibuild is a development acceleration platform that speeds up development processes by distributing tasks across multiple machines, either on-premises or in the cloud. It enhances DevOps processes with parallel execution and distributed builds, significantly reducing build times.

By leveraging idle CPU cycles across your network, Incredibuild transforms your build machines into a private cloud of computing power. This acceleration applies to a wide range of build tools and compilers, making it a versatile addition to your CI/CD toolkit. 

To integrate Incredibuild seamlessly with your workflows, it’s crucial to understand the fundamentals of the GitHub Actions architecture. Whether you’re comparing GitLab to GitHub for your CI/CD needs or diving into advanced tools for specific languages, Incredibuild provides exceptional acceleration for workflows involving computationally intensive tasks. 

For developers working with C++, leveraging C++ GitHub workflows can significantly enhance build times and improve efficiency. Incredibuild’s ability to distribute tasks across multiple machines makes it a game-changer for C++ builds, where long compilation times are a common bottleneck.

By integrating Incredibuild, you can achieve faster feedback loops and better resource utilization, empowering your team to work smarter and deliver results more quickly.

Integrating Incredibuild with reusable workflows

To integrate Incredibuild with your GitHub reusable workflows, follow these steps:

  • Set up Incredibuild coordinator and agents: Install the Incredibuild Coordinator and set up the Initiator and Helper Agents on your build machines.
  • Configure self-hosted runners: If using self-hosted runners, install Incredibuild on these machines and associate them with your Incredibuild Coordinator.
  • Modify the workflow YAML: Update your workflow YAML file to include steps that invoke Incredibuild commands. For example:

jobs:

  build:

    runs-on: self-hosted

    steps:

      – name: Checkout code

        uses: actions/checkout@v3

      – name: Build with Incredibuild

        run: ib_console build.sln /build

This configuration checks out the code and uses Incredibuild to build the solution file.

Benefits of using Incredibuild with reusable workflows

Combining Incredibuild with GitHub reusable workflows offers several advantages:

  • Accelerated build times: By distributing tasks across multiple agents, Incredibuild reduces build durations, leading to faster feedback loops.
  • Optimized resource utilization: Incredibuild leverages existing infrastructure efficiently, minimizing idle times and maximizing throughput.
  • Scalability: As your projects grow, Incredibuild scales with your infrastructure, maintaining performance and reliability.

Incredibuild integration enhances build performance and streamlines your development process, enabling your team to deliver high-quality software more rapidly.

Conclusion

GitHub reusable workflows are a powerful feature that can significantly improve your CI/CD pipelines by promoting efficiency, consistency, and collaboration. Encapsulating common processes into reusable templates reduces redundancy and facilitates adherence to best practices across all projects.

When combined with tools like Incredibuild, you can further enhance your workflows to achieve faster builds and deployments. This integration maximizes resource utilization and accelerates feedback loops, empowering your team to respond quickly to changing requirements. 

Embrace GitHub Actions reusable workflows and transform how you manage your CI/CD pipelines today with a free trial of Incredibuild today.