A logo showing the text blog.marcnuri.com
Español
Home»Operations»Triggering GitHub Actions across different repositories

Recent Posts

  • MCP Tool Annotations: Adding Metadata and Context to Your AI Tools
  • Fabric8 Kubernetes Client 7.2 is now available!
  • Connecting to an MCP Server from JavaScript using AI SDK
  • Connecting to an MCP Server from JavaScript using LangChain.js
  • The Future of Developer Tools: Adapting to Machine-Based Developers

Categories

  • Artificial Intelligence
  • Front-end
  • Go
  • Industry and business
  • Java
  • JavaScript
  • Legacy
  • Operations
  • Personal
  • Pet projects
  • Tools

Archives

  • May 2025
  • April 2025
  • March 2025
  • February 2025
  • January 2025
  • December 2024
  • November 2024
  • August 2024
  • June 2024
  • May 2024
  • April 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • April 2023
  • March 2023
  • February 2023
  • January 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022
  • August 2022
  • July 2022
  • June 2022
  • May 2022
  • March 2022
  • February 2022
  • January 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • August 2021
  • July 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • February 2020
  • January 2020
  • December 2019
  • October 2019
  • September 2019
  • July 2019
  • March 2019
  • November 2018
  • July 2018
  • June 2018
  • May 2018
  • April 2018
  • March 2018
  • February 2018
  • December 2017
  • July 2017
  • January 2017
  • December 2015
  • November 2015
  • December 2014
  • March 2014
  • February 2011
  • November 2008
  • June 2008
  • May 2008
  • April 2008
  • January 2008
  • November 2007
  • September 2007
  • August 2007
  • July 2007
  • June 2007
  • May 2007
  • April 2007
  • March 2007

Triggering GitHub Actions across different repositories

2019-12-03 in Operations tagged CI / curl / DevOps / GitHub Actions / Shell / Workflow by Marc Nuri | Last updated: 2021-09-11
Versión en Español

Introduction

In this post, I’ll show you how one GitHub Actions workflow from a repository can invoke a workflow from a different repository. The first part describes the different events that can trigger a workflow, focusing on the repository_dispatch event. The second part is a practical example showing how two repositories trigger their workflows mutually.

Events that trigger workflows

As you may already know, there are several events that can trigger a GitHub Actions workflow execution. The most common events that can trigger this execution are push, pull_request and schedule. These events cover most of the use cases, as regularly you want your workflows to trigger when certain events happen on the repository. Sometimes this is not enough, and you require a workflow trigger to respond to an external event (chatbot, external CI, manual deploy to prod after QA, etc.).

This is where the repository_dispatch event can be used (in this post it will be utilized to trigger workflows across different repositories).

In order to trigger this event, you need to send an HTTP POST request to this endpoint https://api.github.com/repos/:owner/:repo/dispatches.

This endpoint expects 2 input parameters:

  • event_type: This will be received in the workflow event payload as the action field.
  • client_payload: JSON object with any custom information that you want to propagate to the workflow, this will be available in the client_payload field of the event payload.

In order to be able to use the endpoint, you will need to be authenticated and authorized to access the repository. For that purpose, you can create a personal access token.

The endpoint can be invoked by using cURL:

1curl -X POST https://api.github.com/repos/:owner/:repo/dispatches \
2-H 'Accept: application/vnd.github.everest-preview+json' \
3-u $your_user:$your_personal_access_token \
4--data '{"event_type": "$your_event", "client_payload": { "customField": "customValue" }}'

Notice the Accept header has application/vnd.github.everest-preview+json custom media type value. As of now, this endpoint is still in the preview period and the API can change without previous notice.

Triggering events across repository workflows

In order to show how we can use repository_dispatch event to trigger workflow executions from one repository to another, I’ve designed two repository pipelines named A and B:

Actions Remote Dispatch Sequence Diagram
Actions Remote Dispatch Sequence Diagram

There are two repositories, A and B. Repository A will trigger its workflow execution when push or repository_dispatch event is received. Respository B will only trigger its workflow execution when a repository_dispatch event is received.

The sequence starts with a regular push to repository A (there’s also a schedule so that the sequence gets executed at least once a day). This will trigger an initial workflow execution in repository A, this workflow will perform a request to the dispatches endpoint in repository B with a ping action type and end its execution.

Repository B will start a new workflow execution. For the received ping event, the workflow is configured to send a request to repository A with a pong action type and end its execution.

Repository A will start a new workflow execution. For the received pong event, the workflow will send a request to repository B with an ack (acknowledge) action type and end its execution. This will be the last workflow execution in the sequence for this repository.

Finally, repository B will start a final workflow execution. For the ack event, the workflow is configured to simply print an informative message with the name of the repository that invoked the action. The workflow execution ends and the sequence concludes.

Access token

One of the main requirements to be able to perform requests to the repository dispatch endpoint is to use authentication.

First, we must create a personal access token following GitHub’s guide.

Next, we need to set these credentials in a secret in each of the repositories (A & B). For each of the repositories, we’ll access the settings->secrets page and add a new secret named ACCESS_TOKEN. The value for the token will be our username a colon and the personal access token obtained in the previous step (username:token).

GitHub Secrets - Access Token
GitHub Secrets - Access Token

Repository A workflow (ping)

1name: Remote Dispatch Action Initiator
2
3on:
4  push:
5  schedule:
6    - cron: '0 12 * * *'
7  repository_dispatch:
8
9jobs:
10  ping-pong:
11    runs-on: ubuntu-latest
12    steps:
13      - name: PING - Dispatch initiating repository event
14        if: github.event.action != 'pong'
15        run: |
16          curl -X POST https://api.github.com/repos/marcnuri-demo/actions-remote-dispatch-b/dispatches \
17          -H 'Accept: application/vnd.github.everest-preview+json' \
18          -u ${{ secrets.ACCESS_TOKEN }} \
19          --data '{"event_type": "ping", "client_payload": { "repository": "'"$GITHUB_REPOSITORY"'" }}'
20      - name: ACK - Acknowledge pong from remote repository
21        if: github.event.action == 'pong'
22        run: |
23          echo "PONG received from '${{ github.event.client_payload.repository }}'" && \
24          curl -X POST https://api.github.com/repos/marcnuri-demo/actions-remote-dispatch-b/dispatches \
25          -H 'Accept: application/vnd.github.everest-preview+json' \
26          -u ${{ secrets.ACCESS_TOKEN }} \
27          --data '{"event_type": "ack", "client_payload": { "repository": "'"$GITHUB_REPOSITORY"'" }}'

This repository contains the “initiating” workflow. It will be triggered on repository_dispatch but also on push and schedule. Push and schedule events will be used to trigger the initiating ping action. On the other hand, dispatch events will be used to trigger the acknowledge action. Both these executions can be seen in the jobs section of the workflow.

There is only a single job for this workflow with two steps. The first step will trigger only when github.event.action != 'pong'. For our current example, this means that it will trigger for any push or schedule event or any repository_dispatch event which is not of pong type. So every time a user pushes a commit to the repo or every day at 12:00, this step will be executed. The run action is executing the curl command described previously. In this case, the event_type is ping and is targeting repository B, in the custom payload we’re including the name of the current repo available in $GITHUB_REPOSITORY environment variable. Notice also how we set our credentials with the secret defined in the previous step using the expression ${{secrets.ACCESS_TOKEN}}.

The second step in the job will trigger whenever github.event.action == 'pong', which will only happen whenever a respository_dispatch event of type pong is received. This step will (again using curl) send an acknowledgment request to repository B.

Repository B workflow (pong)

1name: Remote Dispatch Action Responder
2
3on: [repository_dispatch]
4
5jobs:
6  ping-pong:
7    runs-on: ubuntu-latest
8    steps:
9      - name: Event Information
10        run: |
11          echo "Event '${{ github.event.action }}' received from '${{ github.event.client_payload.repository }}'"
12      - name: PONG - Dispatch response to received PING
13        if: github.event.action == 'ping'
14        run: |
15          curl -X POST https://api.github.com/repos/marcnuri-demo/actions-remote-dispatch-a/dispatches \
16          -H 'Accept: application/vnd.github.everest-preview+json' \
17          -u ${{ secrets.ACCESS_TOKEN }} \
18          --data '{"event_type": "pong", "client_payload": { "repository": "'"$GITHUB_REPOSITORY"'" }}'

This repository contains the workflow that will be remotely invoked, i.e. it will only be triggered for repository_dispatch events.

The workflow contains a single job with 2 steps. The first step (Event Information) will run always, it basically prints information about the event that triggered the invocation. The second step (PONG) will only run if a ping event action is received, it will send a request (using the described curl command) to repository A with a pongevent_type.

Conclusion

In this post we’ve seen how we can use GitHub Actions repository_dispatch event to trigger workflow executions across different GitHub repositories. The same approach could be used to trigger manual action executions from a remote environment, a different CI tool, a chatbot, etc.

The full source code for this post can be found at Github (A & B).

References

  • Original source
  • External events: repository_dispatch
  • Create a repository dispatch event
  • RepositoryDispatchEvent payload
  • Creating a personal access token for the command line
GitHub Actions
GitHub Actions
Twitter iconFacebook iconLinkedIn iconPinterest iconEmail icon

Comments in "Triggering GitHub Actions across different repositories"

  • Avatar for 48cfu
    48cfu
    2020-09-13 14:35
    Very nice explained. This helped me a lot, thanks!

Post navigation
How to use sets in GoQuarkus + Fabric8 Maven Plugin + GraalVM integration
© 2007 - 2025 Marc Nuri