Automating Blog Releases: Hugo + GitHub Actions

A lot of the work I do professionally involves transforming traditional network culture, practices, and technology. Just as DevOps transformed application delivery, NetDevOps is here to make sure the network can keep up. This post will cover how I deploy this blog with Hugo to GitHub Pages using GitHub Actions to completely automate the workflow. This is very similar to how I approached modernizing network documentation for my current employer. Listen to Day Two Cloud Podcast as I talk through this transformation in more detail.

Docs-as-Code refers to the philosophy that you should be writing documentation with the same tools as code. It is also an easy and non-intrusive way to get traditional engineers started using tools like git which have practical use cases far beyond documentation. Some of the benefits include:

  • Version Control (Git)
  • Incorporating Automation (CICD)
  • Ensure Docs evolve with code (Linked work items)
  • Adopt DevOps practices in network engineering (Priceless)

Static sites are making a comeback! In today’s world, speed and security are kind of a big deal. The more complex something is, the more difficult it is to secure. Static site generators are becoming popular as they bridge the gap between static sites of old, and dynamic sites of today. Benefits of static webpages include:

  • Cost (Fast delivery, low up front cost)
  • Simplicity (Hosting, scaling, and automation)
  • Speed (No backend database calls or dynamic content generation)
  • Security (Less exposure to the internet)

A request can only be made for files that contain HTML, CSS, JavaScript, Images, Audio, or Video. Since there is no database to breach and no server-side platform or CMS, the threat vector doesn’t exist to maliciously control an application or exploit a database.

About Hugo
About GitHub

Hugo is written in GoLang and claims to be the world’s fastest framework for building websites. At <1 ms per page, the average site builds in less than a second. It doesn’t take many cycles to get acclimated with writing in Markdown, and Hugo’s Shortcodes help you extend functionality to new heights.

About GitHub
About GitHub

Since everyone knows what GitHub is and are probably already experts at using git, this doesn’t require much explanation. If you are not an expert, then have a look here to educate yourself. You may not know as much about GitHub Pages and GitHub Actions.

GitHub Pages allows you to host a webpage directly from your GitHub repository. This is a great way to showcase your blog, portfolio, project, documentation, or anything else you are interested in sharing with the world. With no databases to setup and no servers to build, you can focus more on content and less on management.

All your host provider has to do is serve static assets. Since they don’t need to support a specific programming language or framework, this makes it simple to host, manage, and even migrate to another hosting provider. Professionally, I am using Pivotal Cloud Foundry on Azure to host a NetDevOps DocSite.

About Actions
About Actions

GitHub Actions enable you to automate your workflow. I have been using Azure Pipelines quite a bit recently for continuous integration and continuous delivery (CI/CD) . With the exception of a few things, GitHub Actions worked in a very similar way and is a breeze to setup. I would imagine GitHub Actions will be leveraged largely by the open source community as GitHub is geared for open source projects.

There are a few different ways you can deploy a static site using Hugo on GitHub Pages. I like the idea of keeping my source code in a dedicated repository and generating the contents of the site to an external repository. For me, this seems much cleaner than building the content inside the same repository and lends itself more to to a logical branching strategy.

  • User/Org or Project repo setup - Instructions here
  • Hugo source repo setup (This repo can be private, and the naming convention doesn’t matter)
  • Hugo site committed to source repo (To develop or other integration branch)

To enable the ability to push from source to destination repo, we need to generate SSH keys.

# Private key added as a secret in Hugo source repo
# Public key added as deploy key in GitHub Pages repo
ssh-keygen -t rsa -C "hugo_deploy" -b 4096 -f ~/.ssh/hugo_deploy

Navigate to settings on the source repo and create a new secret with the name ACTIONS_DEPLOY_KEY. Use your private key contents as the Value for the secret.

Source Repo
Source Repo

On the GitHub Pages repo, we need to create a Deploy Key. The naming convention doesn’t matter, but should be descriptive like - Deploy Key Pub. Use the public key contents as the Key.

Destination Repo
Destination Repo

Since I am the only one contributing to this blog, the branching is pretty simple. I create a branch for a given post and merge back with develop (integration) branch. Once I am ready to release a new post, I create a pull request and merge back with master. The workflow looks something like this:

Blog Workflow
Blog Workflow

Add .github/workflows/deploy_hugo_site.yml to the Hugo source repo. Substitute username/destination-repo with the appropriate GitHub Pages / Destination repo.

Once the code is committed and the workflow gets triggered, you can track the progress under Actions in the hugo source repo. The first time a site is deployed to GitHub Pages, you will have to wait a few minutes for it to be reachable. Subsequent releases should update within a few seconds.

If you want to check out some popular alternatives to Hugo, check out Jekyll and Gatsby. In integrating these types of tools into a technical workflow, you are not force-fitting writer-centric tools onto engineers but rather fitting the documentation into developer-centric tooling.