DEV Community

Cover image for Reusable GitHub Worfklows
Kera Cudmore
Kera Cudmore

Posted on • Originally published at keracudmore.dev

Reusable GitHub Worfklows

I was recently tasked with performing a spike at work to see if we could implement reusable workflows. My team maintain a large number of python repositories, each one containing several workflows to perform specific CI tasks (linting, code formatting etc) that must pass before a pull request can be reviewed.

With our current setup, making a change to the workflow, for example updating an action version, would require us to make the update in the workflow and create a pull request in each python repository. This however takes valuable developer time which could be used on more important tickets and created overhead as we would need to keep track of which repositories have been updated.

Reusable workflows looked like they may be a solution to our problem. A reusable workflow is pretty much what it says on the tin, a workflow that is declared, and can then be called from other repositories to run the jobs in the reusable workflow. By implementing reusable workflows, we would be able to save developer time as the change needed would only need to be made in one workflow, and make having to remember which repositories had been updated redundant, as no changes would be need to be made in the calling repositories, only the reusable workflow.

I'm pleased to say that my spike was a success, allowing us to drastically reduce the workflow files in our repositories to a single CI workflow that calls off to our reusable workflow repository. It has been a great learning experience to dive into workflows, jobs steps and actions, and even to work with conditional logic to only run certain jobs and steps in certain cases.

Obviously I can't share private work code, so I've written a simple reusable workflow below as an example of how you can set one up. For further information on setting up reusable workflows to be called from private reposititories, passing inputs or secrets, and more advanced usage etc see the GitHub official documentation in the resources section at the end of this post.

Setting up a simple reusable workflows for HTML validation

Create a reusable workflow

You can call reusable workflows from within the same repository where you will be calling the reusable workflow from, but for this example I've create a new repository to store all my reusable workflows in one central place.

  1. In the repository create a .github folder and within that a workflows folder.

  2. Create your reusable workflow file - I've called mine html_validation.yml

on:
  workflow_call:

jobs:
  html:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4.2.2

      - name: validate-html
        uses: Cyb3r-Jak3/html5validator-action@v7.2.0
        with:
          root: .

Enter fullscreen mode Exit fullscreen mode

As this is the reusable workflow that will be called, we need to include the trigger on: workflow_call. This is what allows the workflow to be called from other repositories.

This is a simple workflow with one job called Validation, and two steps - the first performs a checkout of the repository, then we validate the HTML using the Cyb3r-Jak3/html5validator-action action.

Call a reusable workflow

Now we need to declare the calling workflow - this is the workflow in our repository that will calling the reusable workflow.

  1. Provide the trigger you would like the workflow to be called on in the calling repository - this example is calling the workflow on a push to the main branch, but you could set this up for on a pull request, or other branches etc. Take a look at the GitHub documentation to get an idea of the types of triggers you could use for your own workflows.

  2. Next we'll declare a job, Validate and call off to our reusable workflow with the uses.

  3. The format for calling our reusable workflow is:

    <GitHub Username> / <Repository Name> / .github / workflows / <filename> @ <branch>

name: CI

on:
  push:
    branches: [main]

jobs:
  Validate:
    uses: kera-cudmore/example-reusable-workflows/.github/workflows/html_validation.yml@main

Enter fullscreen mode Exit fullscreen mode

Ok time for the results!

When we push a change in the calling repository, we can view the workflows runs in the actions tab, and then select the run with your commit message:

GitHub Actions page displaying the CI workflow runs

We are then shown a summary of the CI job - showing the workflow file that triggered the run ci.yml, and the jobs run, Validate and html.

GitHub Actions page displaying the CI workflow run details page

Clicking on the validate/html jobs box will then show you the steps detail page. You can expand the steps to view more information, for example the inputs passed in or the commands run as part of the step.

GitHub Actions page displaying the steps detail page

This expanded view is very useful to debug when a job fails, as you can see at which step the job failed and view the logs. The example below shows that the html validation step failed as element p is not allowed as a child of element h1 - this gives us an area of the code to check, and points to the h1 tag not being closed.

GitHub Actions page displaying the steps detail page with a failed step and its logs

I've included the two repositories I created for this post in the resources below, feel free to fork them and play with the workflows.

Resources


Do you use reusable workflows to do something fun in your repositories? Never used them before but think you'll give them a go? Let me know in the comments below 😊

Retry later

Top comments (0)

Retry later
Retry later