Using GitHub Actions to publish this site

Since 2019 this site has been built with Hugo. Until today I used a Makefile target, included as an addendum for historical interest. I decided this morning that I’d switch this over to use GitHub actions and write up the experience.

This post was going to be substantially longer, presumably containing a load of stuff about creating a custom GitHub action that used a customised container with Hugo inside, figuring out how to get the site published to the gh-pages branch, then committing it and pushing it. I thought committing back to a different branch in the repository from within the GitHub Actions runtime might end up being harder than I expected. At any rate, I figured the post would be quite helpful and fancy.

But it turns out that last July GitHub added the ability to use GitHub Actions directly to publish to GitHub pages, bypassing the gh-pages branch completely. There is even a template for using Hugo. Creating a workflow from that template worked first time 👌.

That was quick – and I suggest anyone still using a Makefile target or custom action switch over. It’s a nice system. I can now publish to the site from a Git client on my phone. Should I ever want to.

My old Makefile

Included primarily for my own memory of git tricks like how to test the current branch is clean. The idea is to clone another copy of the repo somewhere, then build the site into the copy’s gh-pages branch before committing and pushing the changes from the copy.

The make target first checks that the current branch is committed. Don’t want to end up publishing something which doesn’t match the commits in the repo. Of course, the GitHub Action only runs on commits to main so no tricks needed there.

Then we clone the repository to /tmp/dx13-hugo-deploy. The gh-pages branch is checked out in that folder – it’s the publish destination. git -C <DIR> tells git to treat DIR as the working directory. Cleaner than changing the directory using cd.

I use --filter=blob:none to speed up cloning the repository. It lazily downloads the blobs when a branch is checked out, meaning that only the blobs needed for the gh-pages branch are downloaded.

The script next uses hugo to build the site from the main branch into the folder holding the gh-pages checkout. Then we commit all the changes using a generic message and push it. GitHub then deploys.

CLEAN=$(shell git status --porcelain)

	# Check whether there are uncommitted changes; fail if so
	test -z "$(CLEAN)"

	- rm -rf $(DEPLOYDIR)
	mkdir -p $(DEPLOYDIR)
	git clone --filter=blob:none \ $(DEPLOYDIR)
	git -C $(DEPLOYDIR) checkout gh-pages
	hugo -d $(DEPLOYDIR) -b ""
	# .nojekyll prevents GitHub running Jekyll
	touch $(DEPLOYDIR)/.nojekyll
	git -C $(DEPLOYDIR) add .
	git -C $(DEPLOYDIR) commit -m "Publish site"
	git -C $(DEPLOYDIR) push
← Older
More, Smaller, Things
→ Newer
My earliest attempts to counter SQL injection