Incremental Gatsby Builds with GitHub Actions
Tags: gatsby, github
Published: 2020-10-14 11:35:30

If you build a large website with [Gatsby](https://www.gatsbyjs.com/) or use Gatsby in combination with a CMS such as [GraphCMS](https://graphcms.com/), the build can take a long time. For this reason Gatsby offers the option of an incremental build, see [Conditional Page Builds](https://www.gatsbyjs.com/docs/conditional-page-builds/). I hope this post helps you to reduce the build time.

**TL;DR**

* Use the environment variable `GATSBY_EXPERIMENTAL_PAGE_BUILD_ON_DATA_CHANGES` to enable conditional page builds.
* Persist the `.cache` and `public` directories between builds.

## Behind the Scenes

In my example I used Gatsby in combination with GraphCMS and [GitHub Actions](https://github.com/features/actions). Whenever a change is made in the CMS, an [Amazon Lambda](https://aws.amazon.com/de/lambda/) function is triggered by a Webhook, which then triggers a build in GitHub Actions. If you want to learn more about it, check out the following blog post:

{% link marcostreng/static-site-builds-with-github-actions-and-graphcms-3edi %}

## How to use

Use the environment variable `GATSBY_EXPERIMENTAL_PAGE_BUILD_ON_DATA_CHANGES=true` in your `gatsby build` command to enable conditional page builds.

```
GATSBY_EXPERIMENTAL_PAGE_BUILD_ON_DATA_CHANGES=true gatsby build --log-pages
```

The `--log-pages` parameter will output all the file paths that were updated or deleted at the end of the build stage.

You will need to persist the `.cache` and `public` directories between builds. This allows for comparisons and reuse of previously built files.

## Github Actions

To persist the necessary directories I use GitHub [cache](https://github.com/actions/cache) action.

```yaml
- name: Caching Gatsby
  id: gatsby-cache-build
  uses: actions/cache@v2
  with:
    path: |
      public
      .cache
    key: ${{ runner.os }}-gatsby-build-${{ github.run_id }}
    restore-keys: |
      ${{ runner.os }}-gatsby-build-
```

The `key` is a unique cache identifier. This is important because you cannot currently update the cache manually after a build run. So after each build a new cache is created. 

Caches that have not been accessed within the last week are cleared.

`restore-keys` is a list of alternative keys that will be used to find the previous cache.

The complete GitHub Actions Workflow looks like this:

```yaml
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'
      - name: Caching Gatsby
        id: gatsby-cache-build
        uses: actions/cache@v2
        with:
          path: |
            public
            .cache
          key: ${{ runner.os }}-gatsby-build-${{ github.run_id }}
          restore-keys: |
            ${{ runner.os }}-gatsby-build-
      - name: Installing dependencies
        run: yarn install
      - name: Building Gatsby site
        run: yarn build --log-pages
        env:
          GATSBY_EXPERIMENTAL_PAGE_BUILD_ON_DATA_CHANGES: true
          CI: true
```

---

If you have any kind of feedback, suggestions or ideas - feel free to comment this post!