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/.
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@v4Caching 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/.