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,
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
The use of the GitHub Actions workflow to publish to GitHub Pages, rather than
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
Next, go to
Actions in the top navigation for your repository, and hit
New Workflow in the top left.
hugo and select the
Hugo (by GitHub Actions) workflow. Hit
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
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
Configure for the
It can also be set up later, by editing the
hugo.yml file that will be added
.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
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
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
draft is set to
false in your frontmatter:
--- title: "A post for the far future" date: 2100-01-01 draft: false ---
publishDate can be used to hold up publication even
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 🌟