đ Zola, okay we'll do it your way.
On building/publishing a Zola-managed site.
2021-11-03
#static-site-generator #github-actions #ci-cd
I'd previously mentioned that I was
maintaining a fork of Zola to allow me to use my old deployment model: that of
having a separate, public repo. which housed my built static-site and
referencing this as a Git submodule residing the public
subdirectory.
While that works, the overhead of maintenance the fact I'm doing Something Different⢠forced me to re-evaluate and decide that I should just RTFM and do it Zola's prescribed way.
Zola/GitHub Pages
Zola already publishes
guidance on
how to deploy your site to GitHub Pages.
Specifically, it makes use of
GitHub ActionsâGitHub's in-house CI/CD
toolâto run the zola build
command and publish the resulting, generated files
to the appropriate place.
One of GitHub Actions' best features is the library of already-built
"actions"
available (slow builds? Try a
cache. Need to share build
artefacts betweens steps? Try
upload-artifact/download-artifact)
and indeed, there's already one for doing precisely this thing:
zola-deploy-action
.
Configuration
All GitHub Actions are configured via YAML files, located
in a repository's .github/workflows/
subdirectory (see GitHub's
docs. for details.)
There does seem to be some drift between the examples provided in
Zola's documentation
versus that of
zola-deploy-action
itself. For instance, the former uses actions/checkout@v2
to manage the
git checkout
of the repo. whereas the latter uses actions/checkout@master
.
While both seem to work, the former is seemingly more ubiquitous (in my personal
experience, that is.)
To decide on what steps need to be taken, I need to answer two questions:
- when is it going to do it?
- what is it going to do?
When is it going to do it?
Specifically, what is going to happen to trigger the build of the website? In
this case: when a new commit arrives on the main
branch or when I need to
make it happen manually.
There are many events that can trigger a workflow but for my purposes, the following (a slight variation on the examples) does the trick:
on:
push:
branches:
- main
So whenever I git push origin main
, GitHub Actions will run the workflow.
Notably, this doesn't just run on git push
but also when, for instance, a
pull-request is merged and new commits appear on main
.
GitHub Actions do not by default have the means to manually run workflows. Instead, there's some specific configuration that needs to be added to give one the option. So, extending the above, I arrive at:
on:
push:
branches:
- main
workflow_dispatch:
What is it going to do?
To start with the example provided by Zola:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v2
- name: build_and_deploy
uses: shalzz/zola-deploy-action@v0.14.1
env:
# Target branch
PAGES_BRANCH: gh-pages
# Provide personal access token
TOKEN: ${{ secrets.TOKEN }}
There are a few things to note in here:
- the workflow will run on an
ubuntu-latest
image (quite why every workflow I've ever seen runs on Ubuntu I'm not sureâare there really no other, underlying images in GitHub Actions?!) - the workflow then runs a series of
steps
(theuses
value dictates what is run; thename
is simply a label):actions/checkout
will rungit checkout
(specifically of the Git ref. which triggered the processâin our case,main
); the@v2
suffix dictates which version ofactions/checkout
it will run;- it will then run the
zola-deploy-action
(v0.14.1
of which seems to maintain parity with releases of Zola itselfânice.)
It's the env
section which needs some consideration. Herein I can set a series
of environment variables which will change the behaviour of the action (a pretty
standard pattern.) In the example above they've set:
PAGES_BRANCH
which dictates the branch to which the resulting static pages will be pushed;TOKEN
which holds the GitHub personal access token which authorises this whole process to take actions on a user's behalf.
The TOKEN
setup is covered in both Zola's and GitHub's own documentation so
there's little reason to repeat that here. The rest, however, now require some
thought.
env
zola-deploy-action
documents
several environment variables which can be configure to change behaviour.
Starting with the above, and noting only where I need to change default
behaviour:
PAGES_BRANCH
: as noted above, I want to maintain a separate, public repo. for the final, static site. The code therein will be dedicate to hosting said code so it makes sense that themain
branch will serve as the "live" site, thus this should bemain
;REPOSITORY
: continuing the above, by default this derives fromGITHUB_REPOSITORY
, one of GitHub's default environment variables, populated by the name of the current repository; as per the above, this should be the name of the other, public repository (in GitHub's username/repository-name format);
Although not required, there are a couple which might be worth mentioning:
BUILD_FLAGS
: although this defaults to empty, it's worth noting as one of the examples sets this to--drafts
which I do not want, nor is it clear what the default isâI can safely omit it, however;BUILD_ONLY
: noting only as, again, there's no explicit default mentioned (which isfalse
and this can be safely omitted);BUILD_THEMES
: as I have no themes, I could comfortably set this tofalse
âfor the sake of fewer lines, however, I'll omit it entirely.
So, with the above in mind, what I end up with is:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v2
- name: build_and_deploy
uses: shalzz/zola-deploy-action@v0.14.1
env:
PAGES_BRANCH: main
REPOSITORY: PsypherPunk/PsypherPunk.github.io
TOKEN: ${{ secrets.TOKEN }}
Did it work?
In short: yes.
In more detail: a little too well.
Having added the workflow and pushed the code, it ran and pushed the
newly-minted pages to the remote repository! Success! Well, mostly: it appears
I'd omitted the draft = true
metadata from some content so the newly
published site was a little over-populated. Nothing some hasty editing and
another push couldn't fix, however.
One thing to note is the the final git push
is a
git push --force
which completely nukes the Git history of the target branch. While that's
largely fine in my case, if REPOSITORY
was the current repo. and
PAGES_BRANCH
was set to the current branch, things could (theoretically) end
rather badly.
Otherwise, I'm now doing things ProperlyÂŽ.