Skip to content
Latchkey

How to Build Then Deploy a Static Site in One CI Pipeline

Separating build and deploy into two jobs keeps the deploy minimal and lets you reuse one build for many targets.

Run the framework build (Vite, Next export, Astro, Hugo, Jekyll, Gatsby, Docusaurus) in a build job, upload the output as an artifact, then download and deploy it in a second job.

Steps

  • Build the site and upload the output with actions/upload-artifact.
  • Add needs: on the deploy job so it waits for the build.
  • Download the artifact and run the deploy command.
  • Keep secrets only on the deploy job.

Workflow

.github/workflows/ci.yml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build   # or: hugo, npx astro build, gatsby build
      - uses: actions/upload-artifact@v4
        with:
          name: site
          path: dist
  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: site
          path: dist
      - run: ./deploy.sh dist

Gotchas

  • Static export commands differ: next build then next export (or output: export), jekyll build -d _site, hugo -d public.
  • Artifact names must be unique per run when a matrix builds several variants.
  • Deploy from the artifact, not a fresh build, so both jobs ship identical bytes.

Related guides

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