Publish your next Hugo blog post automatically using Github Actions

The Challenge

I wanted to be able to publish a new post that has already been written at a future date, without needing to manually publish the article.

The Solution

Github Actions.

I already push updates to my site using github actions. So I thought why not have articles published in the future after they are written.

A little background. I do all my edits in a private GitHub repo. When I push to master in this repo. A workflow action is triggered that causes my live site to be updated. The automatic merge that this system creates, results in my live site being updated without my taking further actions. See my previous post.

How I implemented this: I added the file publish.yml to my .github/workflows folder.

Note: cron runs based on UTC time. So you will need to take that into account when you define your cron job’s time.

If you need some help understanding the crontab format. I would refer you to crontab.guru

name: Publish Future Article
on:
  schedule:
    - cron: '30 0 8 8 *' # Publish at 00:30 on August 8th UTC time.


jobs:
  createPullRequest:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          ref: site-update

      # Required to make this commit ahead of the actual push
      - name: Make changes to pull request
        run: date +%s > lastAutoUpdate.txt

      - name: Create Pull Request
        uses: peter-evans/create-pull-request@v3.1.0
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          commit-message: Ready to publish
          committer: GitHub <noreply@github.com>
          author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
          signoff: false
          base: master
          branch: PublishArticle
          title: 'PublishNewArticle'
          body: |
            Testing to publish a new article.            
          labels: |
            automerge            

This published my new article at 00:30 on August 8th UTC.

Note:

  1. ref: site-update tells the action which branch to copy to generate the pull request.
  2. base: master tells the action which branch the pull request should be merged into.
  3. branch: PublishArticle the new temporary branch that the pull request will create. It will be deleted by the auto merge action listed below.
  4. The automerge label is needed to trigger the next action script that follows.

The next thing to do is to create an action that will actually merge this new pull request.

I created a file again in the .github/workflows called automerge.yml.

This file contains:

name: automerge
on:
  pull_request:
    types:
      - opened
  status: {}
jobs:
  automerge:
    runs-on: ubuntu-latest
    steps:
      - name: Merge pull requests
        uses: pascalgn/automerge-action@v0.9.0
        env:
          GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
          MERGE_DELETE_BRANCH: true

I think this whole workflow could be improved to add more useful information to the generated pull_request. Something to consider.

In order to use these actions in the current form. You will need to edit the cron: time each time you want to have an article published in the future. Also note that cron does not support year. So if you leave this cron in place. It will run at the same time each year.

I should also point out that the merge actually triggers a push to master. This results in the live site being updated from this private repo.


See also