Static site builds with GitHub Actions and GraphCMS
Tags: graphql, github, javascript, gatsby
Published: 2020-08-05 13:02:43

In this blog post I'd like to show you how to trigger a GitHub Actions Workflow from [GraphCMS](https://graphcms.com/) to deploy your static site with the latest content.

As GitHub requires a specific payload we need to set a small function between GraphCMS and GitHub. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8y0f2kfh1xhg04bodvdg.png)

This example uses AWS Lambda for the serverless function and Amazon S3 for storage. Of course you can use the cloud provider of your choice.

## Overview - What we need to do

1. GitHub Actions workflow
2. GitHub access token
3. Lambda function
4. GraphCMS webhook 
5. Test it!

### 1. GitHub Workflow

Our workflow should build the static recourses and deploy them. We use [Gatsby](https://www.gatsbyjs.org/) as static site generator. So our workflow should be straightforward. The only special one is the trigger `workflow_dispatch`. More about this later.

```yaml
name: Deploy on GraphCMS Publish Event

on: [workflow_dispatch]

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js
        uses: actions/setup-node@v1
        with:
          node-version: '12.x'
      - run: yarn install
      - run: yarn lint
      - run: yarn test
      - run: yarn build
      - uses: actions/upload-artifact@v2
        with:
          name: public
          path: public/
 deploy:
    name: Deployment
    runs-on: ubuntu-latest
    needs: [build]
    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js
        uses: actions/setup-node@v1
        with:
          node-version: '12.x'
      - uses: actions/download-artifact@v2
        with:
          name: public
          path: public/
      - run: yarn install
      - run: yarn serverless:deploy
```

### 2. GitHub Access Token

To trigger our workflow from 'outside' we need to create a personal access token on GitHub. 

Login to GitHub and goto `https://github.com/settings/tokens`. Create a new token and save it anywhere secure, we will need it later.

### 3. Lambda function

Our Lambda function will be called by the GraphCMS webhook. The function then will call the GitHub API and trigger our GitHub workflow. 
We will call the `worklow_dispatch` endpoint which we use as trigger in our GitHub workflow in step 1. ([GitHub Docs](https://docs.github.com/en/rest/reference/actions#create-a-workflow-dispatch-event))

```javascript
const axios = require('axios')

exports.handler = async (event) => {
  const { status } = await axios.post(
    'https://api.github.com/repos/[OWNER]/[REPO]/actions/workflows/[WORKFLOW-FILENAME]/dispatches',
    { ref: 'master' },
    {
      headers: {
        Accept: 'application/vnd.github.v3+json',
        Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
      }
    }
  )

  if (status === 204) {
    return {
      statusCode: 200,
      body: 'GitHub API called'
    }
  }

  return {
    statusCode: 400
  }
}

```

You will have to change `[OWNER]`, `[REPO]` and `[WORKFLOW-FILENAME]` with your data. The GitHub token we created in step 2 is stored as an environment variable (`process.env.GITHUB_TOKEN`).

Parameter `ref` in the request body is required by GitHub. You can specify your branch name here.

### 4. GraphCMS webhook 

Login to GraphCMS and create a new webhook. Paste the Lambda endpoint into the `Url` field. GraphCMS allows you to choose `Content Model`, `Stage` and `Action` to control when our webhook is triggered.

(Of course you should care about security and also work with an Authorization Header here)

### 5. Test it!

Depending on which triggers you configured in the GraphCMS webhook settings (mostly `publish` and `unpublish`) you now can trigger a build and see your workflow running on GitHub.