Skip to content

Publish to GitHub Pages ​

GitHub Actions workflow to build and deploy static sites to GitHub Pages.

When to use ​

Use this GitHub Actions workflow when you need automated static site deployment that builds, tests, and deploys to GitHub Pages on every push to main.

The pattern ​

Create .github/workflows/publish-to-github-pages.yaml:

yaml
name: Publish to GitHub Pages

on:
  push:
    branches: [main]
    paths: ["src/**", "scripts/**", "package.json"]
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  publish-to-github-pages:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run tests
        run: npm test
      
      - name: Build site
        run: npm run build
      
      - name: Setup Pages
        uses: actions/configure-pages@v4
      
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: "./dist"
      
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

Verification checklist ​

  • Workflow file exists at .github/workflows/publish-to-github-pages.yaml
  • Repository has GitHub Pages enabled in Settings > Pages
  • Source is set to GitHub Actions in Pages settings
  • Build output directory matches path in upload artifact step
  • Tests run before deployment
  • No hardcoded secrets in workflow
  • Concurrency controls configured
  • Using single deployment method (Actions only, not classic Pages)

Trade-offs ​

  • Trigger strategy: Use push triggers for current docs, tag triggers for releases
  • Path filters: Customize paths array to trigger only on relevant changes
  • Node version: Use LTS versions (18, 20) for stability
  • Build output: Common paths are ./dist, ./build, ./public, ./out