GitHub Actions Pages Deployment

GitHub Pages hosts static websites straight from a repository at no cost for public projects. A workflow can build your site, upload the result, and publish it on every push. The method suits portfolios, documentation, blogs, and project landing pages.

Pages Deployment in Simple Words

Picture a print shop. You hand over your design files, the shop prints them, and a delivery truck places the finished posters in a public gallery. The workflow is the print shop, the built site is the poster, and GitHub Pages is the gallery.

Enable Pages for Actions

Open Settings, choose Pages, and set Source to GitHub Actions. The setting tells GitHub to accept deployments from workflows instead of a branch.

The Deployment Pipeline

+---------+     +-----------+     +-----------------+     +--------------+
| Push to | --> | Build job | --> | Upload site as  | --> | Deploy job   |
| main    |     | (npm run  |     | Pages artifact  |     | publishes to |
|         |     |  build)   |     |                 |     | github.io    |
+---------+     +-----------+     +-----------------+     +--------------+

Complete Workflow

name: Deploy Site to Pages

on:
  push:
    branches: [ main ]
  workflow_dispatch:

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

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

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
      - run: npm ci
      - run: npm run build
      - uses: actions/configure-pages@v5
      - uses: actions/upload-pages-artifact@v3
        with:
          path: ./dist

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - id: deployment
        uses: actions/deploy-pages@v4

Action version numbers change over time. Confirm the latest tags on each action page in the GitHub Marketplace before copying this file.

What Each Part Does

Permissions

The pages: write scope lets the workflow publish. The id-token: write scope lets the deploy action prove its identity to Pages.

Concurrency

The group named pages allows only one deployment at a time. Setting cancel-in-progress to false lets a running deployment finish instead of stopping halfway.

Build Job

This job installs dependencies, creates the final files in a folder named dist, and packages that folder as a Pages artifact. A plain HTML site skips the build commands and uploads its root folder directly.

Deploy Job

The deploy job receives the artifact and publishes it. Its environment block makes the live address appear on the run page.

Folder Names by Tool

ToolBuild CommandOutput Folder
Plain HTMLNoneRepository root or a chosen folder
Vite or Vuenpm run builddist
Create React Appnpm run buildbuild
Jekylljekyll build_site

Your Site Address

Project sites appear at https://username.github.io/repository-name/. A repository named username.github.io publishes at the shorter address https://username.github.io/. Many tools need a base path setting that matches the repository name, or pages load without their styles.

Custom Domains

Open Settings, then Pages, and type your domain in the Custom domain box. Create a CNAME record at your domain provider that points to username.github.io. GitHub issues an HTTPS certificate automatically after the records propagate.

Troubleshooting

  • A 404 page after deployment often means the upload path is wrong or the base path is missing.
  • A failed deploy with a permission message means the pages or id-token scope is absent.
  • Styles that fail to load point to absolute paths. Switch to relative paths or set the base path.

Every merge to main now updates the live site within a minute or two. The workflow log shows each stage, so a broken build never replaces a working site.