Keeping Hugo Upto Date With Github Actions
By jjm
It’s been about 5 months since I moved this blog over to a static site build with Hugo and in this time I’ve never really gotten round to updating Hugo following new releases. So the solution that jumped out recently was to automate upgrades via GitHub actions.
Finding out the current release is very easy as Hugo is hosted on GitHub, plus they publish releases. This means it’s possible to get the tag for the latest version with Javascript as follows:
const latest_release = await github.repos.getLatestRelease({
owner: "gohugoio",
repo: "hugo"
});
const new_ver = latest_release.data.tag_name.replace('v', '');
The reason for the Javascript choice (over normally Python) is the GitHub actions team have created actions/github-script, which makes it really easy to run (but not debug errors) Javascript as you get A pre-authenticated octokit/core.js client (plus more). This makes and this makes raising a PR and then commenting on an issue only a few lines of code:
steps:
- uses: actions/github-script@v3
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const pull = await github.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
head: branch_name,
base: "main",
title: title,
body: body,
});
await github.issues.createComment({
issue_number: issue_num,
owner: context.repo.owner,
repo: context.repo.repo,
body: `I've auto created a PR (#${pull.data.number}) to update Hugo :tada: :cowboy_hat_face:!`
})
Also in early 2020 we got GitHub Actions: New workflow features which included outputs support for jobs. This made it possible to pass outputs from step in one job to another instead of writing them to the environment within a job, so it’s as simple as:
jobs:
create-issue:
name: Create GH Issue
runs-on: ubuntu-latest
outputs:
cur_ver: ${{ steps.issue.outputs.cur_ver }}
new_ver: ${{ steps.issue.outputs.new_ver }}
issue_num: ${{ steps.issue.outputs.issue_num }}
Then in any jobs that needs
this job can just reference the outputs:
env:
CUR_VER: ${{ needs.create-issue.outputs.cur_ver }}
NEW_VER: ${{ needs.create-issue.outputs.new_ver }}
ISSUE_NUM: ${{ needs.create-issue.outputs.issue_num }}
With this info, it’s possible to update the script which installs Hugo in the pipeline (it’s worth noting that
with the default GitHub token it’s not possible to update the workflow file directly due to the lack workflow
permissions) and then push it a branch and then open a PR!
So we now have enough building blocks to put all this together into a workflow:
Which we can run multiple times a week and on demand, which will open an issue and PR for us to review and merge to update Hugo to the newest release.
on:
schedule:
- cron: "0 08 * * 1-5"
workflow_dispatch:
I completed this workflow post the release of Hugo v0.81.0
, so it’s only run for a single new release of Hugo so
far, but I’m looking forward to the next release being so much simpler.
These same concepts could be used for other tooling (e.g. upgrading Hashicorp Vault) and with the ability to re-use actions across repos. It would not be too hard to make this standalone action that can be reused. Plus when support arrives for actions being hosted in private repos it’ll not need to be public either!
I’ve now been using GitHub actions since late 2019 and it just keeps getting more powerful!