Automating Deployment of a Hugo Site to GitHub Pages with GitHub Actions

May 26, 2021

GitHub, GitHub, What?

Well, I’m not affiliated, by the way ;P GitHub pages is a service freely available for all GH users to host static sites from their repositories. GH actions (also free, as in free lemonade) lets users automate software workflows (think CI/CD). What we’ll be doing is automating the deployment of a Hugo site in a GH repository to GH pages.

Setting up the source

Once we have a Hugo site set up1, we’ll need to push this to a repo in GH. This could be the same repo we’ve setup GH pages as well, but for my Hugo blog, I’ve used a different one that doesn’t use GH pages. Here, GH actions of this (source) repo needs to clone the GH pages repo to commit, and push to it whatever the changes. For git authentication in this case, a deploy key2 with write access (default is read-only) shall be created for the GH pages repo. This key shall then be added to the source repo as a repo secret (i.e. with name DEPLOY_KEY). That way, the deploy key shall be made securely accessible by GH actions of the source repo.

Actions Workflow

We may as well set up GH Actions in the same repo for GH pages, commit and push the changes to own repo on a trigger. However, following workflow3 is to be used in setting up GH actions in the source (non GH pages) repo.

# This workflow clones a repo, builds the Hugo site in it, 
#   and pushes the pages (/public dir) to another repo.

name: Build and Deploy Hugo site

# Controls when the action will run. 
on:
  # Triggers the workflow on push or pull request events but only for the main branch
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

  # Allows us to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build_and_deploy"
  build_and_deploy:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out our (source) repository under $GITHUB_WORKSPACE, so our job can access it
      - uses: actions/checkout@v2
        with:
          path: <dir-to-checkout-source-repo>

      # Sets up Hugo binary in environment
      - run: |
          mkdir -p $GITHUB_WORKSPACE/bin/hugo/
          cd $GITHUB_WORKSPACE/bin/hugo/
          wget https://github.com/gohugoio/hugo/releases/download/v0.83.1/hugo_0.83.1_Linux-64bit.tar.gz
          tar -xzvf hugo_0.83.1_Linux-64bit.tar.gz
          chmod +x hugo          
       
      # Checks-out GH pages repo, git auth with deploy key (with write-access)
      - uses: actions/checkout@v2
        with:
          repository: <gh-username>/<gh-repo-name>
          path: <dir-to-checkout-GH-pages-repo>
          ssh-key: ${{ secrets.DEPLOY_KEY }}
      - run: |
          cd $GITHUB_WORKSPACE/<dir-to-checkout-source-repo>
          $GITHUB_WORKSPACE/bin/hugo/hugo --minify 
          cd $GITHUB_WORKSPACE
          rm -rf <dir-to-checkout-GH-pages-repo>/<path-to-hugo-site>/*
          cp -r <dir-to-checkout-source-repo>/<path-to-hugo-site>/public/* \
                  <dir-to-checkout-GH-pages-repo>/<path-to-hugo-site>/.
          cd <dir-to-checkout-GH-pages-repo>/
          git config user.name github-actions
          git config user.email github-actions@hsen.tech
          git add .
          git commit -m "Hugo site built & updated"
          git push
          echo Pushed at `date`.           

The above workflow is set up to be triggered once every push or pull_request event, uses a specific version of Hugo binary to build the site, and is easily extensible for building multiple sites (with own-directory for each). It goes without saying that there are many ways to accomplish what we’ve just done, and each comes with it’s own tradeoffs.


  1. https://gohugo.io/getting-started/quick-start/ ↩︎

  2. https://docs.github.com/en/developers/overview/managing-deploy-keys ↩︎

  3. Modified version of https://github.com/actions/starter-workflows/blob/main/ci/blank.yml↩︎

HugoDeploymentAutomationGitHub

Automating Deployment of a Django site with GitHub Actions

From Development to Production with a Simple Web Game