Set up a static website with Hugo, Forestry and GitHub Pages

I’m moving a private knowledge base powered by WordPress to a public blog so I seized the opportunity to study a static site generator like Jekyll.

The generator: Hugo

I chose Hugo one of the most popular generators, it’s really simple to use and to extend. Just download the CLI and run it in an empty folder and it will scaffold a basic site structure.

hugo new site quickstart

Then it’s time to download a theme, put it in the themes folder and set the config.toml file. I choose a theme named Soho.

To keep the theme updated I’m going to use a submodule as recommented by the quick start guide.

git submodule add https://github.com/alexandrevicenzi/soho.git themes/soho

Each theme has a lot of customizations that you can enable in the config.toml file.

The editor: Forestry

To manage contents in a web interface it comes in our aid Forestry.io: it reads data from a repository and let you edit pages easily, then it pushes back the changes keeping all synchronized.

The hosting: GitHub Pages

GitHub Pages offers a static site hosting service for free available at https://<username>.github.io. Content is read from the master root folder of a special public repository under https://<username>/<username>.github.io.

I’m going to use two different repositories:

  • one private where manage my contents and build the web site
  • one public to host the generated web site

Every time I make a change on the private repository, I must commit on it, build the web site and then publish all the content to the public repository. This can be done in two ways: using git submodules or using GitHub Actions to automate the deploy; let’s try the second choice.

I’m gonna use an available action here to set up a CD workflow:

name: publish
# on every commit in the master branch
on:  
  push:
    branches: [ master ]
jobs:
  # it starts a job named build
  build:
    runs-on: ubuntu-latest
    steps:
      # it checkout the master branch and init/update the submodules (the themes)
      - uses: actions/checkout@v2
        with:
          submodules: true
          fetch-depth: 0
      # it prepares the hugo command line on ubuntu
      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: '0.76.5'
      # it builds the contents
      - name: Build
        run: hugo --minify
      # it deploys the build on another repository
      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        #docs: https://github.com/peaceiris/actions-gh-pages
        with:
          personal_token: ${{ secrets.PERSONAL_TOKEN }}
          publish_dir: ./public
          external_repository: <username>/<username>.github.io
          user_name: <username>
          publish_branch: master

This task runs at every push:

  1. prepare an ubuntu OS
  2. checkout the code
  3. setup the right version of Hugo CLI
  4. build the web site in a destination folder
  5. publish the result in the public repository with the static hosting service enabled

Here’s an example of the workflow running:

Both repositories are under the same user so you can use a personal token to share permissions across them (another way is to use a deploy key).

You must generate it and put the generated hash in the private repository secrets store so you can use it during the build like in the script example above.

Now you can manage locally a simple markdown file and push it or you can do that online in a rich editor like Forestry and in a few seconds is available online.

Comments

comments powered by Disqus