Skip to main content

Command Palette

Search for a command to run...

A DevOps Guide to Github Actions using Repository Dispatch

Updated
5 min readView as Markdown
A DevOps Guide to Github Actions using Repository Dispatch
B

DevOps & Cloud Engineer|| Tech Lover||

Table of Contents

  • Introduction

  • Repository Dispatch: The MVP of the story

  • Implementation

  • Conclusion

Introduction: What is Repository Dispatch

Let’s paint a scenario, you work in a team with other engineers where a piece of code has just been pushed and merged to a branch, all seems fine right? but wait, the infrastructure repository (repo) which has files such as: docker files, helm files, test files etc. seems to just to be sitting there not doing anything.

Imagine this was a critical workflow. The docker image isn’t being built and pushed to its container repository. The various Helm charts aren’t being updated and committed back to the infrastructure repo. And worse of all the deployment you thought was going on hasn’t even started. How do we fix this? This is where our little friend “repository_dispatch” comes in.

Repository Dispatch: The MVP of this Story

MVP! MVP!! MVP!!! —Words you’ve probably heard a crowd chanting for the best player of a team during an outstanding performance. Think of repository dispatch as that player in our github actions workflow.

How does it work? With this, you can trigger other workflows within the same repository or even in different repositories by means of the repository dispatch event. With a simple API call, workflows can be initiated virtually from anywhere, having your different repositories talking and listening to each other.

Implementation

To implement this, you would need a setup that looks like this:

  • Code Repo (Repository A): A github repo that contains all your application code. It could be frontend or backend codes.

  • Infrastructure Repository (Repository B): Github repo where all infrastructure related files are stored such as: Dockerfiles, Helm charts, deployment scripts, terraform files etc.

  • A yaml file in both repositories where the github actions workflow would reside.

Setting up your action

Repository A

In your workflow yaml file, you give your workflow a name which is what would appear on the github web UI and for purpose of effective git practice a trigger key called “on” that makes it that the workflow is triggered only when a pull request is merged to the branch and in this case the dev branch:

name: our github workflow
on: 
  pull_request:
    type:
      - closed
    branches:
      - dev

Next, you want to add a conditional statement check to ensure it only runs when a pull request is merged:

job:
  dispatch-infra-repo:
    if: github.event.pull_request.merged = true
    runs-on: ubuntu-latest

Next, we’ll setup an action using a curl request that will be responsible for starting the dispatch event. This curl command can also be run via your personal terminal as well.

steps:
 - name: Dispatch event to Infra Repo
   run: |
    curl -X POST \
      -H "Accept: application/vnd.github.everest-preview+json" \
      -H "Authorization: token YOUR_PERSONAL_ACCESS_TOKEN" \
      https://api.github.com/repos/OWNER/INFRA_REPO/dispatches \
      -d '{"event_type": "admin-portal-frontend", "client_payload": {"microservice": "admin-portal", "branch": "dev"}}'

For the commands above to work, Here are the steps to take:

  • Replace <YOUR_PERSONAL_ACCESS_TOKEN> with a personal access token. This token needs to have full repo access and the account in question should also have write access to the target repository. You can learn how to generate a personal access token here.

  • Next, replace <OWNER> and <REPO> with the target owner and the name of the repository. In my case: https://api.github.com/repos/Bishopuko/admin-portal/dispatches

NOTE: The <event_type> is the name of the repository dispatch event that the target action will listen to. This is also the name that would be present on the Github actions web UI, so naming it properly to know what service in your infrastructure is being built would help you greatly and also provides a little trick that will be explained later on in this blog.

Now that all has been configured, the configurations send a payload in JSON format to the repository_dispatch event to a repository_dispatch event we send a payload in a JSON format. This is done by adding the <client_payload> key to the data object and add a JSON object as value.

Repository B

The Code Repo was set to send dispatch events, let’s setup our infrastructure repo to handle those events effectively.

In the workflow yaml file in the infrastructure repo, you need to add a trigger for the “on” key that says that the workflow will accept repository dispatches.

on:
    - repository_dispatch:

You can have multiple workflows that are triggered by separate dispatches. Using specified event types determine what will trigger the workflow. e.g:

on:
    repository_dispatch:
        types: [frontend-deployment]

However, there’s always an exception to every rule, given the scenario that your team has multiple microservices both for different environment (frontend and the backend) and you want each individual microservice to maintain their name and environment to help distinguish them what do you do?

on:
     repository_dispatch:
        types: [*-frontend]

How the snippet above works is by leveraging a wildcard in the repository_dispatch event’s types field to create a dynamic trigger system. This allows your workflow to respond to multiple event types that share a common naming pattern which in this example above: event types ending with -frontend or whatever unique wildcard you decide to implement.

The asterisk (*) acts as a wildcard, meaning the workflow will listen for all repository_dispatch event type, then the wildcard option of your choice which is (-frontend). So this means it is listening and accepting all event_type that ends with my wildcard choice .i.e “-frontend”. This is incredibly helpful as you don’t need to create a separate workflow file for each event_type for systems with basically the same steps in the pipeline process.

EXTRA POINTS

We can harness the power of the <client_payload> in Github Actions to create dynamic and adaptable workflows. Rather than hardcoding values, you can simply pass the data like names, values infact anything you think you don’t want to hardcode can be passed from the payload. This allows us to simplify maintenance by using a single actions file and also adapt to need requirements without modifications.

- name: Checkout infrastructure repository
  uses: actions/checkout@v3
  with:
    path: infra 
- name: Checkout specific microservice repository
  uses: actions/checkout@v3
  with:
    repository: 'bishopuko/${{ github.event.client_payload.microservice }}'
    path: microservice/${{ github.event.client_payload.microservice }}
    ref: ${{ github.event.client_payload.branch }}
    token: ${{ secrets.PAT_TOKEN }}

CONCLUSION

I hope you find this article helpful in incorporating Repository Dispatch into your CI/CD processes using github actions. Do let me know how you’ve implemented or will implement this to your development process via Twitter!

If you found this helpful or have your own unique way of applying Repository Dispatch. I’d love to connect and hear your thoughts. Feel free to connect with me on LinkedIn and Twitter with recommendations, questions or referrals!