Trigger a single workflow via webhook

I think I might be missing something, but is there a way to trigger a specific workflow using a webhook?

For context, there are the regular workflows that build production versions of the app, etc. but I also have a debug build that gets downloaded and used for development, and it only needs to be rebuilt when certain files change.

I’ve found that there’s a concept of selective builds but that’s at the app level and not the workflow level. There’s also incoming webhooks, but those also seem to be at the app level and not at the workflow level.

How do I trigger a specific workflow when a certain file is changed, but leave the rest of the workflows’ triggers unchanged?

I am writing down the full workflow via webhook and Github -

GitHub Actions are similar to any other CI tool, but they come with one great advantage. In terms of functionality, they are not closed to the community. As part of your build process, you can use a function that someone else created, and here comes the cool stuff, just by referencing its codebase.

Why is that cool? Because if you’re missing something in the CI tool, you no longer need to work around it or vote on feature requests. Just implement it or use someone else’s implementation.

GitHub Action Workflow of a Gatsby site

While the feature is called GitHub Actions, the actual build process is called Workflow. Let’s take a look at what the workflow configuration looks like for our Gatsby site:

name: Site build

# workflow triggers
on:
  push:
    branches: [ source ]
  pull_request:
    branches: [ source ]
  workflow_dispatch:

# build process
jobs:
  build:
    name: Build
    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v2.3.1

    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: '14.x'
    
    - run: |
        npm ci
        npm run build

    - name: Deploy 🚀
      if: github.ref == 'refs/heads/source'
      uses: JamesIves/github-pages-deploy-action@4.1.1
      with:
        branch: master
        folder: public
        clean: true

It has two parts—triggers and the actual build process. This workflow can be started by pushing, submitting a pull request to the target branch source , or manually triggering the build from the GitHub UI.

The build job runs the Gatsby build and uses an [action] implemented by [Jameslves] to deploy a generated site to GitHub Pages (that is the Continuous Delivery part of the process).

Adding webhook trigger to GitHub Action

The push and PR triggers solve the need for build in case of code changes. Let’s now add a section after existing triggers that will allow us to start the workflow using a webhook notification:

# workflow triggers
on:
  push:
    branches: [ source ]
  pull_request:
    branches: [ source ]
  workflow_dispatch:

  # Allows external webhook trigger
  repository_dispatch:
    types:
      - webhook

The trigger is called repository_dispatch and you can limit the scope to only specific webhooks with a type. The type can be anything; “webhook” is just something I made up, and for this repo, it’s actually redundant—there’s only a single workflow on top of a single app codebase. However, this can be very useful for monorepos.

To test invoking this trigger, you need to send a special POST request to the following URL:

https://api.github.com/{owner}/{repo}/dispatches

The request also needs to contain the following headers:

"Accept": "application/vnd.github.everest-preview+json"
"Authorization": "token {personal token with repo access}"

You need to provide a personal GitHub token with the repo access scope. If your trigger also features a type, specify it in the request body:

{"event_type": "webhook"}

For instance, here is an example of a GitHub action workflow config that runs when a new blog post is published:

on:
  # publish blog using webhook
  repository_dispatch:
    types: [publish_blog]
 
 # steps

In the case above, we will make a post request to create repository dispatch action endpoint with event_type of publish_blog and that’s when the GitHub Action will get triggered and not by any other event type. Basically I have used this webhook on my best ERP partner in Kolkata in single workflow and related things. The event_type allows you to begin a specific GitHub action workflow.

Triggering the Action

In order to trigger the action above, we are going to send a POST request to the GitHub API endpoint for [creating a repository dispatch event]. The URL follows the following format:

https://api.github.com/repos/[USERNAME]/[REPOSITORY]/dispatches

Replace the [USERNAME] with your GitHub owner i.e. your username or organization and [REPOSITORY] with the name of the repository.

To specify the GitHub Workflow to trigger, you need to provide event_type in the body. The event_type specified must be listed in the types array section of the repository_dispatch .

NodeJS Example

For this example, we are going to use Got, a Node JS library for sending HTTP requests.

const url = 'https://api.github.com/repos/[USERNAME]/[REPOSITORY]/dispatches';
const githubPAT = "GITHUB_PAT"; // keep this secret
await got.post(url, {
  json: {
    event_type: 'publish_blog',
  },
  headers: {
    Authorization: "token " + githubPAT,
  },
});

NB: Remember to substitute [USERNAME] , [REPOSITORY] and GITHUB_PAT with the appropriate values.

The above request is going to trigger all GitHub Actions workflows which are listening to event type publish_blog .

Building a Webhook

Now that we have the basics out, we are going to build a Webhook which we can use to trigger our workflow. While the GitHub dispatch event does qualify to be a webhook, you might want to simplify the API being exposed. This is because some systems where you might want to use the webhook in, will not be that configurable. Some will just give you the option of entering a URL and nothing more, which makes it difficult to use the GitHub Dispatches API directly.

For the purpose of this article, we will be using [Firebase Cloud Functions,] but any rest endpoint will do. This will expose a public GET endpoint that we can pass an action query param, which will be the type of event we want to trigger and will default to publish_blog . We will use [Firebase Functions Config] to pass the GitHub PAT to the function.

export const triggerGithubActionWorkflow = https.onRequest(async (req, res) => {
  const dispatchAction = req.query?.action ?? 'publish_blog';
  const url =
    'https://api.github.com/repos/[USERNAME]/[REPOSITORY]/dispatches';
  const githubPAT = config().github.pat;
  await got.post(url, {
    json: {
      event_type: dispatchAction,
    },
    headers: {
      Authorization: "token " + githubPAT,
    },
  });
  res
    .send({
      message: `Dispatch Github action event emitted successfully!`,
    })
    .status(200);
});

NB: The above Firebase function is public and might wise to add some security measures to prevent anyone from triggering your GitHub Action workflow.

Hope this article helps everyone properly.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.