GitHub pages is a very simple way to host a static website. You can simply commit your html static page and GitHub will serve it as a static content from a github subdomain using your username.

You can even setup your own custom domain if you own one.

The question is how can I host a static website that is generated like Hugo - for people who don’t know, Hugo is a very light and flexible static site generators.

In the following article, I will assume that you are familiar with Hugo, GitHub and especially GitHub actions.

Setup your Hugo repository

The first step that is common to any website would be to host your Hugo codesource in a GitHub repository.

To enable GitHub pages, you need to create a repository named username.github.io and must be a public repository.

In this article, I’m assuming that you have push your Hugo codesource to this repository and know how Git works.

Default GitHub action for GitHub pages

By default when you create a GitHub pages repository, your repository will have a new Action added nammed pages-build-deployement. This action cannot be modify or deleted. We cannot see the definition, but we can have access to the logs to analyze what the action does.

This action is run every time there is a push on the default branch of your repository

The action is divided in three steps:

  • Build
  • Deploy
  • report-build-status We will focus on the first two that we are interesting in.

Build

The build action is meant for building Jekyll project (other static site generators), as we are not using Jekyll this action does nothing.

But it does bundle the output directory content into a tar file and upload the artifact.

Deploy

The deploy action deployes the generated content to GitHub pages, we can see that it is using the actions\deploy-pages@v1 action.

There are no parameter passed to this action, the action is taking the first artifact uploaded in the build to be deployed.

Create our own GitHub action

We can’t use the default GitHub action as we don’t have a way to build our Hugo website, so let’s build our own action.

First step: build Hugo

In order to build our Hugo website, we need to first install Hugo on the machine, hopefully, there is already an existing action for that: peaceiris/actions-hugo@v2 where you can specifiy the Hugo version to install.

After installing Hugo on the machine, we can actually build our website, calling hugo --minify

Now, we need to bundle the output into an archive and upload the artifact. we can use a simple tar command to create the archive. Here is an example: tar --dereference --hard-dereference --directory ./public -cvf artifact.tar .

Finally upload the archive as an artifact, we can use the default GitHub action actions/upload-artifact@main

If we resume our first step, we need to install Hugo, build our website with Hugo, then create an archive and upload it as an artifact. Your GitHub action should looks like the below:

build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: 'latest'

      - name: Build
        run: hugo --minify
        
      - name: Archive build output
        run: tar --dereference --hard-dereference --directory ./public -cvf artifact.tar .
      - name: Upload Artifact
        uses: actions/upload-artifact@main
        with:
          name: github-pages
          path: ./artifact.tar
          if-no-files-found: warn

Second step: Deploy pages

We have now our Hugo website upload as a GitHub artifact. As we noticed earlier the GitHub action deploy is automatically picked to be deployed.

There are few things to know, you need additional permissions to read the artifact content and deploy the page, you need the additional permissions

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

You also need to setup the environment proprerties of this step to indicates that you deploy to the github-pages environment. This was discussed in this issue. With the support of deploying Github pages from custom actions, it is documented here.

 environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}

Once we have everything setup, we call call the actual action actions/deploy-pages@v1

Your yaml for the second step should looks like this:

deploy:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
      pages: write
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - uses: actions/deploy-pages@v1

Final yaml for your GitHub action

Your final yaml should looks like the following:

name: Deploy Github Pages

on:
  push:
    branches: [ "main" ]

  workflow_dispatch:

jobs:
  # Build the content for GitHub Pages
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: 'latest'

      - name: Build
        run: hugo --minify
        
      - name: Archive build output
        run: tar --dereference --hard-dereference --directory ./public -cvf artifact.tar .
      - name: Upload Artifact
        uses: actions/upload-artifact@main
        with:
          name: github-pages
          path: ./artifact.tar
          if-no-files-found: warn

  # Deploy to Github pages
  deploy:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
      pages: write
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - uses: actions/deploy-pages@v1

You can try to run it directly from the Actions menu.

Switch to deploy using Actions

By default, when pushing a new commit to your main branch, it will trigger the default github page deployment action. We want to use instead use the action that we just created.

You can go to your repository, in Settings under Pages section. You can select the source for build and deployment and select GitHub Actions.

You can now run the Action and see your website deployed on your GitHub pages.