I recently migrated my website content away from a traditional web server host to Github Pages.
A key feature that initially inspired me to make this migration in the first place, is to figure out how to make use of Github automated functionality to schedule future post content.
Instead of needing to remind myself to manually rebuild my site and FTP it up to my host when needed, I wanted a way of writing a few articles on the weekend and letting them “self publish” on a specific future date.
In Content Management Systems like WordPress, it’s a trivial task to set your posts publication date to some future time at which point you have the confidence in the post being made publically available on that set future time.
Let’s sit down and achieve the same functionality (and confidence) with Github Pages!
The Gameplan
While I’m not after any kind of granular levels type of publication, I’m completely “ok” with the idea of a scheduled post being made available sometime during a 24-hour period.
There’s a few small things we’re after:
- Create an Access Token
- Create an environment secret with the Access Token
- Configure Jekyll to ignore content with future dates
- Update the Github Pages automation to trigger a page build
- Some kind of scheduled trigger mechanism
Create an Access Token
- Within your Github repo, you can navigate over to https://github.com/settings/tokens
- Click on the “New” button to create a new token
- Give it some kind of human friendly name for yourself, such as “Github Pages Scheduled” or something
- You will need to assign it some permissions. There’s a long list to choose from, but you only need the
public_repo
setting checked - In the last step, copy this token into your favorite password management tool, or wherever you’re storing your passwords. This is a temporary display of your token - you WON’T be able to see it again - so don’t lose it
That covers “step 1”. This token is required, as our automated Github Action will be making use of it when running a job for you.
Create a “Secret” for your new Access Token
- Now that you have your secret generated, open the repository for your GitHub Pages site
- Click on
Settings
then theSecrets
menu option - Create a new secret with the name
USER_TOKEN
, and paste in the token you just created - Save things
Configuring Jekyll
Now let’s update your site’s _config.yml
with some entries:
future: false
timezone: your_timezone (eg. America/Dawson)
- The
future: false
setting configures Jekyll to ignore the publication of content that has a future date-timestamp at the time of a build - For The
timezone
entry, use your local timezone from this list of TZ database time zones
Configuring a Jekyll Post
Once we’ve updated the main site configuration, we can go into the frontmatter of any blog post / content that you want to publish sometime in the future.
Simply update the date
field within the blog posts frontmatter up at the top of the file:
date: 2022-08-07 14:25:52
- The
date
should be in the format ofYYYY-MM-DD HH:MM:SS
- Only the “date” part of that is REALLY necessary, but thanks to the
timezone
setting that we updated in the_config.yml
file, we can achieve some accurate level of a timestamp
So as it currently stands, from now on whenever we push some content up to our Github Page repository, posts tagged with a future datetime stamp will not be published.
The final piece: adding a Github Action
- In your repository, add a
.github/workflows
set of folders - Within the new
workflows
subfolder, createschedule-posts.yml
Let’s take a look at this new .yml
file:
name: scheduling post action
on:
# Triggers the workflow on a scheduled event
schedule:
- cron: '15 6 * * *' # 6:15 AM every day.
# cron: '15 6 * * 1,5,6' will schedule 06:15 every Monday, Friday and Saturday
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Trigger GitHub pages rebuild
uses: wei/curl@master
with:
args: "-X POST -H 'Authorization: token ${{ secrets.USER_TOKEN }}' -H 'Accept: application/vnd.github.ant-man-preview+json' https://api.github.com/repos/${{ github.repository }}/pages/builds"
env:
# You must create a personal token with repo access as GitHub does
# not yet support server-to-server page builds.
USER_TOKEN: ${{ secrets.USER_TOKEN }}
name
: give our Action a nameon
: this is the trigger that the Action will listen for. We’re usingschedule
to run on a schedulecron
: this is our specified time to run our Action schedule. Check the documentation on how to specify thecron
fields, but for my specific use case, I’m fine with just having this Action being run every morning at06:15
. Adjust your own time / specific day as necessary.
The jobs
section is the “meat” of this workflow. Once our cron
hits our specific time, this workflow will activate and run whatever is defined in jobs
.
build
is just the label of our job. We could easily rename this tojob1
runs-on
specifies what platform to execute our Action on, useubuntu-latest
to specify a Github-hosted runnersteps
this is the sequence of tasks that can run commands, run tasks or run other Action automation. There are nostep
limits, so long as your Action is running within the GitHub workflow usage limitsname
this is the name of the job, which is displayed on GitHubuses
this is an existing action to run as part of the entire job. In other words, we’re making use of a pre-existing actions,wei/curl@master
. Note that GitHub action documentation encourages the use of specifying the version number to avoid any future unexpected behaviorwith
this will specify the command-line params to use in conjunction with curl - ouruses
Action.
In our case, we want to make use of the curl
Action to send a POST
request at the endpoint which will trigger a build of the Jekyll site.
Due to security access, we need to specify an Authorization
header, which is created with help from the USER_TOKEN
secret that we created earlier on!
I hope you got something out of this article, and it demonstrates some simple techniques that GitHub Actions can provide for your site!