🚀Hugo: Deploy with GitHub Actions
Apr 14, 2021 23:00 · 834 words · 4 minute read
Setting up automated deployment for my Hugo blog was one of those tasks I kept putting off. You know how it is – the manual process works, so why change it? But once I finally took the plunge with GitHub Actions, I wondered why I waited so long.
This blog you’re reading right now is built with Hugo (a blazingly fast static site generator written in Go) and automatically deploys to GitHub Pages every time I commit a new post. Let me walk you through how I set it up.
How I Started (And Why It Became a Problem)
Initially, I had a pretty simple setup. I kept my blog content in a private repository and had another separate repository for the generated HTML/CSS files that GitHub Pages serves.
My workflow was straightforward but tedious:
- Write a post locally
- Run the Hugo CLI to generate the static files
- Manually commit and push the generated files
This worked fine when I was always writing from my main computer. But try editing a post from a different machine without Hugo installed? That’s when things got frustrating fast.
The Forestry Detour
Looking for a better solution, I moved to Forestry – a git-backed CMS for static websites. It was fantastic! Writing and publishing posts felt effortless, like having a WordPress admin panel for my static site.
When Things Changed
But last year, Forestry dropped deployment support for Hugo sites. Their reasoning made sense from a business perspective:
When it comes to automate your deployments and host your static website on a CDN, it’s the responsibility of a continuous deployment and hosting service. https://forestry.io/docs/hosting/.
Suddenly, I was back to manual deployments. That’s when I finally embraced GitHub Actions.
Enter GitHub Actions
GitHub Actions is GitHub’s built-in automation platform. Think of it as a way to tell GitHub: “Hey, whenever I push code to this repository, run these specific tasks automatically.”
For my blog, those tasks are:
- Take my Hugo source files
- Generate the static website
- Push the generated files to my GitHub Pages repository
The best part? It’s surprisingly beginner-friendly once you understand the basic structure.
The Solution: Automated Deployment
Here’s the exact GitHub Actions workflow file I use. Don’t worry if it looks intimidating – I’ll break it down after:
# Workflow to help you get started with Hugo deployment
name: Deploy
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
push:
branches: master
# 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 "deploy"
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 your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
# Github Actions fo Hugo
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: "0.81.0"
# Creates ./public directory
- name: Build
run: hugo --minify
# Upload/Commit the contents from publish_dir -> external_repository
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
external_repository: aneesahammed/aneesahammed.github.io
publish_branch: master
personal_token: ${{secrets.GH_TOKEN}}
user_name: aneesahammed
user_email: aneesahammed@mail.com
publish_dir: ./public
Breaking It Down
Let me explain what each part does in plain English:
The Trigger: on: push: branches: master
means “run this workflow whenever I push code to the master branch.”
The Job Steps:
- Checkout: GitHub grabs my repository files
- Setup Hugo: Installs Hugo version 0.81.0 on the virtual machine
- Build: Runs
hugo --minify
to generate my static site - Deploy: Takes the generated files and pushes them to my GitHub Pages repository
Setting Up Your Personal Token
The trickiest part is the personal_token
requirement. Since we’re pushing to an external repository (your GitHub Pages repo), you need to give GitHub Actions permission to do that.
Here’s how:
- Go to GitHub’s token settings
- Generate a new personal access token with repository permissions
- Add it to your blog repository’s secrets (Settings → Secrets → Actions)
- Name it
GH_TOKEN
Key Configuration Points
If you’re setting this up for your own blog, you’ll need to change these fields:
- external_repository: Your GitHub Pages repository (usually username.github.io)
- publish_branch: The branch your GitHub Pages site serves from (usually master or main)
- user_name and user_email: Your GitHub credentials
For more detailed Hugo setup options, check out the Hugo Setup GitHub Action.
The Payoff
Now every time I commit a new post or make changes to my blog, GitHub automatically:
- Builds the site
- Deploys it to GitHub Pages
- Shows me a nice green checkmark when it’s done
No more manual builds. No more remembering to push generated files. Just write, commit, and let GitHub handle the rest.
If you’re running a Hugo blog and still doing manual deployments, I can’t recommend this approach enough. The initial setup takes maybe 30 minutes, but it’ll save you hours down the road.
Got questions about setting this up? Feel free to reach out on Twitter