DEV Community

Cover image for Refactoring GitHub Actions Workflow
Justin Yoo for Microsoft Azure

Posted on • Originally published at

Refactoring GitHub Actions Workflow

A while ago, I wrote a blog post about Azure DevOps Pipelines refactoring technics. GitHub Actions is also suitable for building CI/CD pipelines. But, compared to Azure DevOps, there are many spaces to achieve the same efficiency level as Azure DevOps. GitHub Actions has recently released a new feature called "Reusable Workflows", which you can reduce the refactoring concerns. Throughout this post, I'm going to refactor the existing Azure Static Web Apps CI/CD pipeline workflows, using the "reusable workflows" feature of GitHub Actions.

Workflow for Azure Static Web Apps

While provisioning an Azure Static Web Apps (ASWA) instance, GitHub Actions workflow is automatically generated by default. Here's a sample workflow. I'm pretty sure it's not that different from yours.

The problem is that once you provision the ASWA instance, you can't change the name of the auto-generated workflow file. Therefore, you are only allowed to modify the file.

Let's imagine a situation. You've got a codebase that deploys to multiple Azure Static Web Apps instances – DEV, TEST and PROD, which is pretty common. In that case, you will have as many GitHub Actions workflow files as the number of ASWA instances. But all the workflow files are virtually the same as each other except their filenames. So if you refactor those workflows, the overall process would be more simplified.

For the refactoring practice, you would use the workflow_dispatch event, together with the webhook event, to call the refactored workflow. Once it's set up, unless the access token gets invalidated, you'll be able to use the workflow. But what if the access token is expired or compromised? You MUST reissue the token, which is less ideal. How can we work out this situation?

Reusable Workflows (or Called Workflow)

The reusable workflows use the newly introduced event called workflow_call. It reuses the workflows at the job level. Let's refactor the workflow above. Copy both build_and_deploy_job and close_pull_request_job jobs and paste both into a new YAML file, which is called either "reusable workflow" or "called workflow".

According to the workflow above, there are input variables and secret variables and other variables:

  • Event Object
    • Event Name: github.event_name
    • Event Action: github.event.action
  • Secrets
    • Azure Static Web Apps API Token: secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_XXXX_XXXX_XXXX
    • GitHub Token: secrets.GITHUB_TOKEN
  • App Locations
    • Web App: app_location
    • API App: api_location
    • Web App Artifact: output_location

The "called" workflow can't directly access those values defined in the "caller" workflow. Therefore, they MUST be propagated from the "caller" workflow to the "called" workflow. Let's update the variable parts in the "called" workflow like below (line #7-8, 20-21, 23-24, 30-31, 33-34, 36-37, 43-44, 54-55).

All values have become parameterised. Now, you need to define them in the "called" workflow, under the workflow_call event. All non-secret variables go under the inputs attribute (line #6-21), and all the secret variables go under the secrets attribute (line #23-27).

Now, the refactoring has been completed!

Caller Workflow

Let's update the existing ASWA workflow. As both jobs defined under the jobs node are no longer necessary, delete them. And define a new "reusable" workflow like below:

  • Called Workflow (line #14-15): <org_name>/<repo_name>/.github/workflows/<reusable_workflow_filename>@<branch_or_tag>
  • Input Variables (line #17-22): Under with
  • Secret Variables (line #24-26): Under secrets

Now, regardless of the number of "caller" workflows, update them like above. You only need to update the "called" workflow then all ASWA pipelines will get the updated workflow applied, which is really convenient!

So far, I've shown how to refactor the Azure Static Web Apps workflow with the reusable workflows feature of GitHub Actions. I'm sure that it's not just for ASWA but also can be utilised in many different scenarios.

Top comments (2)

smakinson profile image
Shawn Makinson

This is interesting, thanks for sharing. Have you expanded on this concept with env vars and GitHub environments?

justinyoo profile image
Justin Yoo

@smakinson Thanks for the comment! I personally haven't tried the GH Environment yet, but it's on my radar to extend this refactoring technique. I assume it should be doable, by the way.