Unlocking Seamless Deployments: Crafting a CD Pipeline with HyGraph Webhooks, Serverless Functions, and GitHub Actions!
Tags: webdev, githubactions, cms, serverless
Published: 2023-11-14 23:23:30

So, your company relies on **HyGraph** as the primary **Content Management System (CMS)**, a tool you find enjoyable to work with due to its user-friendly interface, GraphQL API, and seamless integrations with Cloudinary, AltText, and more.

You successfully built and deployed your **static website**, everything works great, and everyone is happy. 

![Happy Face Meme Emoji](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5rr30jpxh6ov3nbsq55v.png)
A few days later, someone at your company messages you and says that they updated content on HyGraph and published it, but they don't see any changes on the website.

And it is the moment when you realize that you need a CD pipeline: all your pages are statically generated at the build time causing the new content from HyGraph not to show up on the website, and you have a choice: you can do it manually - _rebuild the pages and upload to your hosting platform or automate it_.

What should you choose? 
As developers, we always go with the second option - even if it takes more time than doing stuff manually (not in this case, at least in the long term).

![Developer Automation Meme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/acsrx6pkmeysotdx9x5i.png)

---

## So, you decided to automate it. 
## What do you need for this?

First, you need a **GitHub Actions workflow** that will rebuild our website with the latest data from HyGraph.
If you are not aware of Github workflows, basically it is an automated process that will run one or more jobs when triggered.
You can read more about it in this [article by GitHub](https://docs.github.com/en/actions/using-workflows/about-workflows).

A simple GitHub workflow can look something like this:

```
name: Name of the workflow

# when it should be triggered
on:
  - push
  - workflow_dispatch

jobs:
  # job name
  cypress-run:
    # running tests

  # another job
  build:
    # steps to build your pages
```

The logic for the build process would vary based on what library/framework you used.

For us, the most important part here is when the workflow is triggered. There are a lot of ways to trigger the GitHub Actions workflow - in our example, it starts on the push to the repository and on workflow dispatch.

## And probably you have a question - what the heck is workflow dispatch?

Basically, workflow dispatch allows us to trigger workflow manually using the GitHub API, GitHub CLI, or GitHub browser interface.

So, how it can help us achieve our goal? As mentioned above, we can use Github API to trigger our workflow and that is exactly what we gonna do.

---

## We have a GitHub Actions workflow that rebuilds our pages and can be manually triggered using **Github API**. Now what?

The next step would be to somehow trigger it with the help of GitHub API.
How? By making a **POST** request to this endpoint:
`https://api.github.com/repos/OWNER/REPO/actions/workflows/WORKFLOW_ID/dispatches`

You have to replace **OWNER, REPO and WORKFLOW_ID** with the actual data (workflow id should be the name of a file (with extension) - **deploy.yaml** as an example)

Plus, you have to provide one required body parameter - **ref** which is the git reference for the workflow. The reference can be a branch or tag name.

It is the simplest way we can use this endpoint but if you want to know more - feel free to go through [GitHub docs on this particular topic](https://docs.github.com/en/rest/actions/workflows?apiVersion=2022-11-28#create-a-workflow-dispatch-event).

Now, we know the endpoint we should use to trigger the workflow and the only problem left is where to make this call.

---

Probably while working with HyGraph you've seen the **"Webhooks"** tab in the menu but never got a chance to learn more about it.

Probably it would be the perfect time to do this!
Why? 

**HyGraph WebHooks** is a method designed to detect changes that happen to content within your project.
This means that we can be notified whenever new content is published, or existing is updated, by subscribing to these events, and then perform our own custom logic.

Cool, does it basically mean that we can just use Webhook, send a POST request to the Github API endpoint we discussed above and that's it, everything would work like a charm?

---

In an ideal world, yes! But there is one minor problem that won't make it as easy as you think.

As was mentioned above, when sending a POST request to this endpoint (https://api.github.com/repos/OWNER/REPO/actions/workflows/WORKFLOW_ID/dispatches), we also need to send a body with the **ref parameter** set to either tag or branch name.

Maybe you worked with other CMS tools such as Contently, and DatoCMS, and with these tools, this logic would work perfectly fine cause their webhooks implementation has a feature of **customizable payload** - which means you can modify the body (data) you send with your requests.

Unfortunately, in HyGraph there is no such feature yet (but I got in touch with one of their sales representatives and he confirmed that it should be released soon, but did not give a specific timeline).

---

Because of this, we need a **Serverless Function** that will serve as a middleman whose entire purpose would be to add this **"ref"** parameter to the body of the request and actually make this POST request
 
I hope you are all familiar with the concept of serverless functions, but if not, you can read this [short article by Cloudflare](https://www.cloudflare.com/learning/serverless/why-use-serverless/).

You can use AWS Lambda Functions, Azure Functions, GCP Cloud Functions or any other implementation of serverless function. 
Up to you!

I am going to use Azure Functions, and here is an example of how the implementation of that function should look like: 

```
 const axios = require("axios");
  let data = JSON.stringify({
    ref: "main",
  });

  let config = {
    method: "post",
    maxBodyLength: Infinity,
    url: "https://api.github.com/repos/OWNER/REPO/actions/workflows/WORKFLOW_ID/dispatches",
    headers: {
      Accept: "application/vnd.github+json",
      "Content-Type": "application/json",
      Authorization:
        "Bearer GITHUB_PERSONAL_ACCESS_TOKEN",
    },
    data: data,
  };

  axios
    .request(config)
    .then((response) => {
      context.log(JSON.stringify(response.data));
    })
    .catch((error) => {
      context.log(error);
    });

  return { body: `OK` };
```

My Azure Function uses Node.js as a runtime and thus I use Axios to make a request. But you can use any other programming language based on your preferences.

The most important part here is that we construct the body of our request and include the **"ref"** parameter set to **"main"** (branch name, but can tag name as well).

> Don't forget to change the OWNER, REPO, WORKFLOW_ID and GITHUB_PERSONAL_ACCESS_TOKEN with the actual data.

---

Now, when you have your serverless function ready and live, it's time to configure HyGraph Webhook.

1. Go to the **"Webhooks"** tab and click the **"Add"** button.

2. Configure your webhook - give it a **name**, and a **short description** of what it does, choose the **method**, and provide the **serverless function public URL** (make sure, your serverless function is accessible)
![HyGraph Webhook Configuration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2vg0wnmujwzx2g5b2eun.png)

3. Choose which models, actions, and stages should trigger this webhook
![HyGraph Webhook Configurationn](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nwuximlcmj88mbnfbmna.png)

4. Click the **"Add"** button at the top.

And here we go! You just created your HyGraph Webhook.

---

Now, your CD pipeline is ready!

Whenever you make a change to your content in the HyGraph and publish it (or unpublish), it triggers a webhook that makes a call to the serverless function, which then sends a POST request to the Github API and triggers workflow which fetches the latest data from HyGraph, rebuilds the pages and pushes updated content to the hosting platform. 


![CD Pipeline Structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jurgfj1vymyx0isvgkdj.png)

---

And that's it, guys.

I hope that you have learned something new today!
I would appreciate it if you could like this post or leave a comment below!

Also, feel free to follow me on [GitHub](https://github.com/Kai4ik) and [Medium](https://medium.com/@kai4ik)!

Adios, mi amigos)


![Grumpy cat saying bye bye](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0laqf22pdnmqojy76k04.jpg)