Triggering GitHub Actions From Outside of GitHub

An introduction to using custom repository dispatch events to trigger GitHub Actions from outside of GitHub.

Often, GitHub Actions are configured to trigger in response to common GitHub events, such as pushing a git commit, opening a pull request, or creating a git tag. But how can GitHub Actions workflows be triggered from events outside of GitHub? GitHub’s repository_dispatch event offers a solution.

A basic example

First, create a .github/workflows/repo_dispatch_example.yml file (the name is arbitrary, though its location and .yml extension do matter):

name: Hello

on:
  repository_dispatch

jobs:
  greet:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Say-Hello
        run: echo "Hello!"

After committing and pushing the .github/workflows/repo_dispatch_example.yml file, the Hello workflow’s greet job can be triggered via a GitHub API request (note that this assumes a GITHUB_TOKEN environment variable whose value is an authorized GitHub personal access token):

curl \
  --header "Accept: application/vnd.github.v3+json" \
  --header "Authorization: token ${GITHUB_TOKEN}" \
  --request "POST" \
  --data '{"event_type": "hello"}' \
  "https://api.github.com/repos/<OWNER>/<REPOSITORY>/dispatches"

As a result, the Hello workflow is triggered and its Say-Hello step prints Hello!.

A slightly more advanced example

The above Hello workflow implementation responds to any properly issued repository dispatch API request. However, GitHub Actions also supports the ability to configure workflows that only respond to specific events, as well as the ability to pass arbitrary data to the workflow via the repository dispatch API request payload. The following variation of .github/workflows/repo_dispatch_example.yml is only triggered by repository dispatch API requests whose event_type is hello, and also uses a name from the request payload’s client_payload field:

name: Hello

on:
  repository_dispatch:
    type: ["hello"]

jobs:
  greet:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Say-Hello
        run: echo "Hello, ${{ github.event.client_payload.name }}!"

The new Hello workflow can be triggered like so:

curl \
  --header "Accept: application/vnd.github.v3+json" \
  --header "Authorization: token ${GITHUB_TOKEN}" \
  --request "POST" \
  --data '{"event_type": "hello", "client_payload": {"name":"Mike"}}' \
  "https://api.github.com/repos/<OWNER>/<REPOSITORY>/dispatches"

This results in a Say-Hello step that prints Hello, Mike!, as seen in this example.

However, requests whose payloads specify an event_type other than hello, such as the following, no longer trigger the Hello workflow:

curl \
  --header "Accept: application/vnd.github.v3+json" \
  --header "Authorization: token ${GITHUB_TOKEN}" \
  --request "POST" \
  --data '{"event_type": "goodbye"}' \
  "https://api.github.com/repos/<OWNER>/<REPOSITORY>/dispatches"

Gotchas

Based on experimentation, it seems requests to repos/<OWNER>/<REPOSITORY>/dispatches only trigger workflows whose .github/workflows/*.yml configuration exists in the repository’s default branch.