How to trigger a GitHub action workflow in another repository
7 Feb 2024Do you need to trigger a GitHub action workflow from another workflow? This is possible! You can use the GitHub API to trigger a workflow from basically anywhere. Let's dive into how this works and think of some practical use cases where this could be handy.
In this blog post I'm going to trigger a GitHub action workflow from a workflow in another repository. I'll reference to these repository by "target repository" and "trigger repository".
The repository dispatch event
At the base of this is the "repository dispatch event". This is an event that can be triggered using the GitHub API and can be acted upon by listening to the repository_dispatch
Webhook event payload.
Documentation about the GitHub API endpoint can be found here and documentation about triggering the workflow based on the event can be found here. This should be enough information to get you going. However, if you want a practical example, please read on!
Target action
This article is not about all the fancy stuff you can do with GitHub actions. This means that the target action will be an incredibly simple one that only serves to prove that the functionality is working.
According to the docs we need to use the repository_dispatch
activity type and specify the type of the dispatch we want to listen to. Let's create the following action in the target repository:
name: Receive repository dispatch event
on:
# Listen to a repository dispatch event by the name of `dispatch-event`
repository_dispatch:
types: [dispatch-event]
jobs:
log:
runs-on: ubuntu-latest
steps:
- name: Event received
run: echo "Event received"
This action will start once it receives a repository dispatch message of the type dispatch-event
. Then all it will do is log "Event received" to the shell, just to prove it works.
Trigger action
Next, we'll setup an action in the trigger repository that will be responsible for firing the repository dispatch event. This is done by sending a request to the GitHub POST /repos/{owner}/{repo}/dispatches API endpoint. Let's use the following curl command to do this.
curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer <YOUR-TOKEN>" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/<OWNER>/<REPO>/dispatches \
-d '{"event_type":"<EVENT-TYPE>"}'
There is a few things we need to replace to make the request work.
Personal access token
Replace <YOUR-TOKEN>
with a personal access token. The access token needs to have full repo
access and the account that is connected to the personal access token should at least have write access to the target repository. If either of these two things is not setup correctly the API will return Error: fatal: repository 'https://github.com/<OWNER>/<REPOSITORY>' not found
.
Make sure to use a secret when using your personal access token in the GitHub action. This prevents leaking it.
Owner and repository
Replace <OWNER>
and <REPO>
with the target owner and the repository. In my case: https://api.github.com/repos/ngnijland/repository-dispatch-target-repo/dispatches
.
Event type
Replace <EVENT-TYPE>
with the name of the repository dispatch event that the target action will listen to. In this example: dispatch-event
.
The trigger action
Now create an action in the trigger repository that executes the curl command. For our example this action looks like this:
name: Send repository dispatch event
on:
workflow_dispatch:
jobs:
trigger-event:
runs-on: ubuntu-latest
steps:
- name: Fire event
run: |
curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.REPOSITORY_ACCESS_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/ngnijland/repository-dispatch-target-repo/dispatches \
-d '{"event_type":"dispatch-event"}'
This action can be triggered manually. In its turn it will sent the repository dispatch request using the GitHub API.
Tip: You can use the Repository Dispatch action from the actions marketplace for better readability.
The result!
That's how it's done!
Passing context
To send extra information with the repository dispatch event you can send a payload in JSON format. Do this by adding the client_payload
key to the data object and add a JSON object as value.
# ...
-d '{"event_type":"dispatch-event", "client_payload": {"message": "Hello from the trigger repository!"}}'
To read it in the target action use ${{ github.event.client_payload.<KEY> }}
.
# ...
run: echo ${{ github.event.client_payload.message }}
Resulting in:
Note: If you want to send files you can upload the files as an artifact in the trigger repository, send ${{ github.run_id }}
in the client_payload
and then download the artifact in the target repository using the run-id option.
When to use this?
Now you know how it works you can unleash all your creativity to apply this to day to day tasks! Some ideas on where to apply this:
- Open PR's in other repositories that update the dependency version of the dependency you just released using GitHub actions.
- Upload e2e test reports as artifacts and download them in the target repository to deploy them to GitHub Pages (we do this at Polarsteps!).
- Trigger a deployment of any sort of internal tool. Using this method you can move the source code of these tools to a separate repository. Preventing you from cluttering the main repository.
- Don't restrict yourself to a trigger action. You can trigger an action from anywhere using the GitHub API. Did someone say something about a physical launch button?! ;)
Conclusion
I hope you learned how to use repository dispatch events to trigger GitHub workflow actions. Hopefully, it sparks some inspiration to start using it for day to day processes. Please let me know of any ways you will or already have implemented this via Twitter! I'm curious about all your implementations!
If you liked this article and want to read more make sure to check the my other articles. Feel free to contact me on Twitter with tips, feedback or questions!