🔁 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?

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:

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:

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:

Although not required, there are a couple which might be worth mentioning:

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®.