Skip to content
Latchkey

CI/CD for Gatsby with GitHub Actions

Build your Gatsby site fast by caching the .cache directory between runs.

Gatsby builds can be slow because of data sourcing and image processing, so caching matters more here than for most stacks. This recipe builds the site, persists Gatsby caches across runs, and deploys the public/ output.

What the pipeline does

  • install deps with npm ci
  • lint with eslint
  • restore the Gatsby cache
  • build with gatsby build
  • upload public/
  • deploy to GitHub Pages

The workflow

The actions/cache step persists .cache and public across runs so Gatsby can do incremental builds. The build emits public/.

.github/workflows/ci.yml
name: CI
on:
  push:
    branches: [main]
  pull_request:
permissions:
  contents: read
  pages: write
  id-token: write
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - uses: actions/cache@v4
        with:
          path: |
            .cache
            public
          key: gatsby-${{ hashFiles('package-lock.json') }}-${{ github.sha }}
          restore-keys: |
            gatsby-${{ hashFiles('package-lock.json') }}-
      - run: npm ci
      - run: npm run lint --if-present
      - run: npx gatsby build
      - uses: actions/upload-pages-artifact@v3
        with:
          path: public
  deploy:
    needs: build
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment:
      name: github-pages
    steps:
      - uses: actions/deploy-pages@v4

Caching and speed

Caching .cache and public is the single biggest Gatsby speedup; with a warm cache, image processing and GraphQL data sourcing are skipped for unchanged content. Cold builds are still CPU-heavy, so running them on cheaper managed runners such as Latchkey (around 69% cheaper than GitHub-hosted) lowers the cost of full rebuilds.

Deploying

Set pathPrefix in gatsby-config.js and build with --prefix-paths when deploying to a Pages subpath. public/ deploys to Pages, Netlify, Gatsby Cloud alternatives, or S3+CloudFront. The output is fully static unless you use Gatsby SSR/DSG features that need a Node host.

Key takeaways

  • Cache .cache and public to enable Gatsby incremental builds.
  • Use --prefix-paths and pathPrefix for subpath deploys.
  • Build output is public/.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →