Github reusable workflows and how to verify them

In december 2022 GitHub added the ability to share workflows between private repositories, opening the doors for Enterprises to make use of this feature. In this post I will describe how I implemented this in my APISMART Team and how I developed a system to verify changes to the reusable workflow. Basic knowledge of GitHub Actions is assumed.
A working example can be found here: reusable-workflows-with-ci and reusable-workflows-sample-project
Why reusable workflows
I’ll keep this short, since there are enough articles on the internet about this already. The main reason is to reduce the amount of code duplication. This in turn reduces the maintenance load of changing the workflow in dozens of repositories and merging dozens of Dependabot PRs for the same dependency. Additionally all repositories use the same standard to build and test their applications.
Implementation
The reusable workflow is usually stored in the .github repository of the organization. The workflow itself just executes a gradle clean build
in order to build and test our applications. It makes use of the input parameters to allow each caller to specify which java version is needed. This allows even the older projects, which have not migrated to the latest java version, to use this.
The caller side is then very simple.
Verification
It was decided to always use the latest version, meaning that the version is main
. This brings the risk that a change to the reusable workflow may break the builds of all our projects. An alternative would be to semantically version the reusable workflow and use a specific version. But this in turn would bring us back to having to merge dozens of Dependabot PRs for a single change.
Instead, a system was needed which would run the workflow on a test project in order to verify that it still works. First off, the reusable workflow was modified to allow checking out a different repository. This requires allowing to pass in the repository and an ssh key which has read access to that repository. Deploy keys are used to provide read access. See the guide on GitHub on how to create one. The public key is saved as deploy key in the test project and the private key is set as github action secret in the .github repository.
Both values are then passed to the checkout action.
Another workflow is added to the .github repository which uses the new input paratemers. It only runs when either the reusable workflow or itself is changed.
And that’s it.
Now all our repositories use a shared workflow and we have a system in place that ensures that no accidents can occur.
Notes
An unpleasent change was that the name of the status check was changed from build
to build/build
. Which means that we had to adjust the required status check in every repository. I could not find any documentation on the naming of the status check but the assumption is that it is generated from the job name. In the case of reuseable jobs it is caller-job-name/callee-job-name
. This can be avoided at the cost of getting billed for an extra minute on each workflow run which we decided was not worth the cost. For that add a second job with the name build
and set the reuseable job as dependency with the needs
keyword.