Scheduling future publication with Hugo, GitHub Actions and Pages
This site is a static site, pre-built with Hugo and uploaded to GitHub Pages. Static sites do not appear to lend themselves to dynamic functionality, like scheduling posts for later, automatic publication. This is what I believed; I had to be there, at the keyboard, bashing out commands, to upload a new version.
But with a little creativity, it can be done.
A couple of weeks after I started to use GitHub Actions to publish this site, I had three or four posts half-drafted (a result of my goal to post smaller things, less often). I wanted to get them finished, but I thought it’d be good to publish them over time rather than all at once. Idly, I wondered whether Hugo could schedule posts, and thought, “no, of course not, I have to run Hugo”. It was then that it hit me that I’d just got “running Hugo” automated within an Actions workflow. And that Actions must have a way to schedule regular execution of a workflow. A plan for scheduled posts was born.
I’ve been using this setup for a couple of months now to schedule publication. It’s simple and reliable. This post shows how to set this up for any GitHub Pages site that uses Hugo. While this post talks specifics for this setup, I expect the general idea can be made to work with any CI/CD and static site builder.
The outline for this is:
- Set up a GitHub Pages site to be built using Hugo and published nightly using GitHub Actions.
- Show how to write a Hugo post for future publishing. It’ll be caught and published during the nightly scheduled build, but not before.
Let’s get started.
Publishing to GitHub Pages using GitHub Actions
The first step is to create a Hugo website, commit it to Git and upload it to
GitHub. I’ll assume that’s already done. If your site is currently using the
gh-pages
workflow with Hugo, following the steps in this post will convert it
to a GitHub Pages flow using GitHub Actions. If you are starting from scratch,
we’ll go through getting from a newly pushed Hugo site in a repository to a site
published on GitHub’s free domain, github.io
.
Regardless, your site should have a main
branch that is the Hugo “source code”
version of the site. We’ll create a GitHub Action that executes the Hugo build
process and uses its output to publish to the GitHub Pages site for the
repository.
The use of the GitHub Actions workflow to publish to GitHub Pages, rather than
the older gh-pages
-branch-based publish workflow, is the key to scheduled
posts. The Action can be scheduled to run nightly, which enables automatic
publishing of new content.
Create the workflow
First, visit your repository’s Settings
page, then hit the Pages
section in
the left navigation. From there, set the Build and Deployment
source to
GitHub Actions
.
Next, go to Actions
in the top navigation for your repository, and hit
New Workflow
in the top left.
Search for hugo
and select the Hugo (by GitHub Actions)
workflow. Hit
Configure
.
This will open the workflow’s default YAML configuration. We want to make two changes:
- Add a scheduled build to build the workflow every night.
- Optionally, change the version of Hugo.
Run the workflow every night
We can set a schedule
using cron
notation. This is set in the on
field of
the workflow, which controls when the workflow is run:
on:
# Runs on pushes targeting the default branch
push:
branches: ["master"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Daily publish at 05:00Z to allow for scheduled posts
schedule:
- cron: '0 5 * * *'
This is entered in the workflow configuration screen that appears after
selecting Configure
for the Hugo
workflow:
It can also be set up later, by editing the hugo.yml
file that will be added
to the .github/workflows
directory of the repository.
Customise the Hugo version
Further down the workflow’s YAML, the version of Hugo to use is defined. Any
released version of Hugo can be used. Just update HUGO_VERSION
:
Again, this can also be changed later for newer Hugo releases, by editing the
.github/workflows/hugo.yml
file that will be added to the repository.
Finishing up the workflow
Hit Start Commit
in the top right to commit the workflow to your GitHub
repository. Commit the file to the main
branch with a suitable commit message.
Now, both whenever you push a commit and each day at 05:00 UTC, the site will be built using Hugo and published to the GitHub Pages URL set up for the site.
Using from Hugo
This is the simple part. Just ensure the date
is set in the future, and ensure
that draft
is set to false
in your frontmatter:
---
title: "A post for the far future"
date: 2100-01-01
draft: false
---
Alternatively, the publishDate
can be used to hold up publication even
if the date
field is in the past:
---
title: "Today's post will appear in the far future"
date: 2023-04-16
publishDate: 2100-01-01
draft: false
---
Commit and push to GitHub. The site will build immediately, but the future post
will not appear. Come 2100-01-01
at 05:00 UTC, it’ll appear on the published
site after the scheduled build.
And we’re done 🌟