Deploying a hugo site with Github Actions

Using Github Actions to render a hugo-site on push to its Github repository.

Creating a homepage is a simple thing these days. You only have to know how to write posts and deploy it. The deployment can be done with each push to a repository. Building and pushing a hugo site with the help of Github Actions will be shown in this post. The interactions are shown in the usecase diagram below.

usecase diagram

Serving the page locally is usually done with hugo serve --buildDrafts. This is used to test locally-written posts.

Then you want to release your written posts. For this you push your changes with git to the hugo-repo. The hugo-repo, stored on Github, is required. There you store the unrendered hugo site.

My hugo-repo ist private, which is not an issue because Github Actions can access them. Github Actions is the continuous-integration mechanism, which will respond to pushes to the hugo-repo by rendering the new commit and pushing the resulting webpage to the deployment-repo.

Requirements

  • a local terraform installation.
  • a personal github access token, available through the env variable GITHUB_TOKEN.
  • git
  • two Github repositories, which can both be private:
    • a hugo-repo storing the unrendered hugo site; the hugo site can be rendered locally with hugo serve without error
    • a deployment-repo inside which the rendered website will be stored automatically

Setup

For all of this to work, you have to do a multi-step process:

Creating and registering the deployment key

The deployment key is used by Github Actions to copy the website into the deployment-repo. First, the key has to be generated locally:

ssh-keygen -t rsa -b 8192 -C "deploy_key" -f "deploy_key"

Put the following into a main.tf file and modify the repository names to the ones you use. It sets the generated private-key as the Github Actions Secret and registers this private-key for deployment to the deployment-repo by adding its public-key to it.

resource "github_actions_secret" "deploy_key" {
  repository       = "<hugo-repo>"
  secret_name      = "DEPLOY_KEY"
  plaintext_value  = file("deploy_key")
}

resource "github_repository_deploy_key" "deploy_key" {
  title      = "Hugo deployment key"
  repository = "<deployment-repo>"
  key        = file("deploy_key.pub")
  read_only  = "false"
}

Make sure the env variable GITHUB_TOKEN is set in the console. Then run terraform init and terraform apply and execute the plan.

Create and push the workflow file

Github Actions is a continuous-integration mechanism, offered by Github itself. It is possible to run so-called workflows, when certain triggers happen. There are many possible triggers. The one we are interested in is push-trigger. We push to master/main and the workflow renders the hugo site and pushes the rendered website to the deployment-repo.

Go to the root of your hugo-repo and put the following yaml-content into .github/workflows/render.yaml. The file itself says when it gets triggered. You have to update the field external_repository to point deployment-repo and maybe publish_branch to main in case your repo is new. Then commit the changes and push the local hugo-repo repository to your Github hugo-repo repository.

name: CI
on:
  push:
    branches:
      - main
      - master
jobs:
  deploy:
    runs-on: ubuntu-20.04
    steps:
      - name: Git checkout
        uses: actions/checkout@v2

      - name: Download hugo
        run: wget https://github.com/gohugoio/hugo/releases/download/v0.76.3/hugo_extended_0.76.3_Linux-64bit.deb

      - name: Install hugo
        run: sudo dpkg -i ./hugo_extended_0.76.3_Linux-64bit.deb

      - name: Build
        run: hugo --minify

      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          personal_token: ${{ secrets.GITHUB_TOKEN }}
          deploy_key: ${{ secrets.DEPLOY_KEY }}
          external_repository: <your-username>/<deployment-repo>
          publish_dir: ./public
          user_name: hugo-renderer
          user_email: deployment@example.test
          publish_branch: master

Then you can go to your hugo-repo on Github and see the under Actions our workflow running. It should succeed with the steps above. If it fails, you have to look into the exact reason why by clicking yourself to where the error occurs and handle it.

If it succeeded then your deployment-repo should have a new commit, changing the previous content to the newly rendered webpage.

Enable github pages

Enable github pages for the master/main-branch on / (root) for the deployment-repo. How this is done can be read here.

Summary

We set up the deployment-key correctly and commited and pushed the workflow-file.

The hugo-repo contains the hugo-site and the workflow-file. The hugo-repo contains the raw hugo site. Adding the workflow-file to it automates the rendering. The workflow runs the defined steps. At the end it uses the deployment-key we set up to commit the rendered website to the deployment-repo.

In the end the user sets up github pages for the deployment-repo. Then he can view his rendered webpage through the github-pages-url for his deployment-repo.

Fabian Sturm
Fabian Sturm
Student

My research interests include learning improvements, mobile computing and programming.