
Setting Up Webhooks for GitHub Actions
Quick Guide on How to Trigger a GitHub Action via Webhook
August 27, 2019
GitHub Actions are GitHub’s Continous Integration (CI) solution used to automate building, packaging, and testing of software projects. In this post we will be walking through how to set-up a GitHub Action that is triggerable by an external service via the GitHub Webhook API.
The primary use-case we are solving for is that where the data used by an application is not co-located with the code. Examples of this might be:
- Triggering a GitHub Action to build and publish an updated version of a static asset. Eg: A static site with content from a headless CMS API like Prismic, Contentful, Ghost, or other data source.
- Triggering a GitHub Action to deploy an new version to production after a manual approval, that is not accompanied by a code change, but wired-up to Slack, Discord, or other Software.
Getting Started
To setup a webhook we’ll need the following:
- GitHub Action - to build, test, or deploy an application
- An example configuration is provided below.
- Access Token to the GitHub repository
- Source that invokes the Webhook
GitHub Action Set Up
Below is what a typical GitHub Action YAML configuration file may look like.
name: Webhook Example
on: repository_dispatch jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: On my_custom_webhook do ABC...
if: github.event.action == 'my_custom_webhook'
run: |
echo "Hello From my_custom_webhook...doing ABC"
- name: On my_custom_webhook_2 do XYZ...
if: github.event.action == 'my_custom_webhook_2'
run: |
echo "Hello From my_custom_webhook_2...doing XYZ"
The single requirement is the on
value of the target workflow must include
the value: repository_dispatch
. The respository_dispatch
value can be part
of a list of values, or standalone.
If the repository is only ever expected to respond to a single webhook type then
there is no need to define a predicate to check the github.event.action
of the build.
All invocations will be processed by this workflow.
However, we may want to respond to different webhooks within the same repository.
To distinguish between different webhook sources we need to define a predicate that
checks github.event.action
for a value we define. We can then define different run
steps for each of the different webhook types. In the example snippet above not that
we have defined support for my_custom_webhook
and my_custom_webhook_2
.
Next we are ready to feed our custom value into github.event.action
in the GitHub
Action by calling the GitHub API. Let’s aquire an access token so that we can formulate
the appropriate request.
Obtain an Access Token
Before we can trigger our Action via a webhook, we need to obtain an access token.
Follow this guide here: Creating a Personal Access Token for the Command Line
. Only repo
persmission should be needed to trigger the GitHub Action.
Once the access token has been obtained it can be used to invoke the GitHub API to trigger the GitHub Action.
Triggering the GitHub Action
We are finally ready to trigger our GitHub Action. We’ll be using curl to illustrate the required payload.
The request we need to make it to https://api.github.com/repos/:owner/:repo/dispatches
.
Where :owner
is the account that owns the repository, and :repo
is the name of target
repository with the configured GitHub Action.
The request headers will need to include:
- Accept: application/vnd.github.everest-preview+json
- Authorization: token $TOKEN
where $TOKEN
represents our access token
aquired in the previous section.
Lastly, we need to include a JSON body with an event_type
key. The value of
event_type
will be set in github.event.action
that we used in our GitHub
Action configuration.
Putting it all together the request looks as follows:
curl -X POST https://api.github.com/repos/:owner/:repo/dispatches \
'Accept: application/vnd.github.everest-preview+json' \
-H 'Authorization: token $TOKEN' \
-H '{"event_type": "$CUSTOM_ACTION_NAME"}' --data
Note that CUSTOM_ACTION_NAME
corresponds to my_custom_webhook
and
my_custom_webhook_2
in our example workflow YAML above. The value can be any string.
At this point running the curl command should cause a GitHub Action workflow to run for the target repository on GitHub.
Conclusion
This post has been a short guide on how to configure a GitHub Action workflow to respond to custom webhook requests via the GitHub API. Having GitHub Actions be triggerable from ourside of the typical git workflow can be a valuable tool in the automation of common processes.
Additional Guidance and Considerations
Many folks may have noticed that triggering a GitHub Action via an API call is possible, but not directly applicable without extra infrastructure since the invoking party needs to keep secrets, use custom headers, and post a custom JSON body. On top of that many sources for webhooks(eg: Prismic, Ghost, etc.) may not allow you to define much more than a URL. All this quickly rules out direct API access from some third-party to GitHub.
One solution for this is to configure a lightweight application that can broker the request. Keeping in mind that you’ll need to provision, secure, and maintain the additional resource.
Another route would be to use something like AWS API Gateway and AWS Lambda to create an on-demand task to keeps the custom GitHub API request without the need to maintain and secur an additional server.
Best of luck!
Questions and feedback are welcome. Find me on Twitter: @bctellez