derekwelty.com was a Bootstrap 5 single-page site built on the Start Bootstrap Freelancer template. It worked, but it hadn’t been touched in years and updating it required wading through jQuery, a Gulp pipeline, and a bunch of hand-rolled CSS. Time to replace it.
The new stack: Hugo with the Congo theme, deployed to GitHub Pages via GitHub Actions.
Why Hugo
I already run this blog on Hugo + PaperMod via Netlify. The toolchain was familiar, the build times are fast, and Congo gave me a clean profile layout that actually looked like a personal site and not a blog template with the posts removed.
The CI/CD setup
The repo (dcwfz9/dcwfz9.github.io) is a GitHub Pages repo. I wanted to keep the old site on main while building the new one on a hugo-migration branch, then flip over once it was ready.
That introduced a few non-obvious friction points.
Workflow file placement
The workflow has to live on the branch it’s triggering from. I initially put .github/workflows/hugo.yml on main with branches: ["hugo-migration"] and nothing fired. The fix: the file has to be on hugo-migration itself.
Dart Sass via snap is broken in Actions
The standard advice for Hugo + Dart Sass on GitHub Actions is:
- name: Install Dart Sass
run: sudo snap install dart-sass
This fails silently or hangs. The snap daemon isn’t reliable in Actions runners. Replaced it with a direct binary download:
- name: Install Dart Sass
run: |
curl -L https://github.com/sass/dart-sass/releases/download/1.77.8/dart-sass-1.77.8-linux-x64.tar.gz | tar -xz
echo "$(pwd)/dart-sass" >> $GITHUB_PATH
Pin Hugo version to match local
The workflow pulls a specific .deb from Hugo’s GitHub releases. Set HUGO_VERSION to whatever you’re running locally — mismatches cause build failures that are annoying to debug in CI.
env:
HUGO_VERSION: 0.161.1
Environment protection blocks the deploy
GitHub Pages has an “Environment” called github-pages with a branch allowlist. If your source branch isn’t in that list, the deploy job fails with “not allowed to deploy to github-pages.”
Fix: Settings → Environments → github-pages → Deployment branches — add hugo-migration (or whatever your branch is).
Non-fast-forward push after rebasing
After fixing the above, I hit a non-fast-forward rejection when the remote had diverged. Standard rebase resolution:
git pull --rebase origin hugo-migration
git push
The final workflow
name: Deploy Hugo site to Pages
on:
push:
branches: ["hugo-migration"]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
defaults:
run:
shell: bash
jobs:
build:
runs-on: ubuntu-latest
env:
HUGO_VERSION: 0.161.1
steps:
- name: Install Hugo CLI
run: |
wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_withdeploy_${HUGO_VERSION}_linux-amd64.deb
sudo dpkg -i ${{ runner.temp }}/hugo.deb
- name: Install Dart Sass
run: |
curl -L https://github.com/sass/dart-sass/releases/download/1.77.8/dart-sass-1.77.8-linux-x64.tar.gz | tar -xz
echo "$(pwd)/dart-sass" >> $GITHUB_PATH
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
- name: Setup Pages
id: pages
uses: actions/configure-pages@v5
- name: Install Node.js dependencies
run: |
if [[ -f package-lock.json || -f npm-shrinkwrap.json ]]; then
npm ci
fi
- name: Build with Hugo
env:
HUGO_CACHEDIR: ${{ runner.temp }}/hugo_cache
HUGO_ENVIRONMENT: production
run: hugo --minify
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./public
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5
One thing to remember
If you ever merge hugo-migration into main, update the workflow trigger:
on:
push:
branches: ["main"] # was hugo-migration
Otherwise pushes to main won’t trigger a deploy and you’ll spend five minutes wondering why the site isn’t updating.