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 distGotchas
- Static export commands differ:
next buildthennext export(oroutput: 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
How to Deploy a Static Site to GitHub Pages From CIDeploy a built static site to GitHub Pages from GitHub Actions using actions/upload-pages-artifact and action…
How to Inject Environment Variables at Build Time for a Static SiteInject environment variables into a static site at build time using the framework prefix (VITE_, NEXT_PUBLIC_…