This article contains some background to why I wrote this plugin. If you just want to use it, see github.com/ariejan/drone-hugo for details.
I recently moved away from Gitlab + Gitlab CI to a Gitea + Drone setup.
Both Gitea and Drone are lightweight and fast, and let’s be honest, more than enough for
an engineering enthusiast like myself. They now also run on my NAS Homelab Server as docker
containers, which helps to save a few bucks every month in hosting fees.
Hugo#
This website (and a few others I manage) are built using the static site generator named Hugo. It’s written in Go andis super fast:
~/src/devroom.io $ hugo
| EN
-------------------+-------
Pages | 1209
Paginator pages | 0
Non-page files | 13
Static files | 249
Processed images | 0
Aliases | 450
Sitemaps | 1
Cleaned | 0
Total in 3073 ms
Because I like using .scss
and some other goodies, I need to use hugo_extended
.
Drone + Hugo#
There’s an official Hugo plugin for drone, but it has two problems:
- The official documentation is lacking on the use of the extended version of hugo
- When you manage to get the extended version installed, it doesn’t work
As a good open source citizen, I opened up the code and took a look around. At this point I noticed a few more “problems” with this plugin.
The plugin needs to run on multiple architectures, that’s cool, but I’m happy with ye good ‘ole amd64.\
It contains a custom Go program to kick-off hugo builds. I can understand that this is useful for more complex plugins or plugins that are easier written in go because of available libraries. However, all this plugin needs to do is install Hugo and run it.
It supports a metric ton of command line options for Hugo. I understand why that’s important, but I have no use for any of them.
Can I do better?#
I could have taken up the official plugin and try to make it work. The problem here is that it’s a rather complicated piece of software for a rather simple task:
- Download the specified versio of Hugo
- Run
hugo
to generate static HTML files
What I found is that a Drone plugin can be written in whatever. Settings from .drone.yml
are passed
on as environment variables with a PLUGIN_
prefix.
So, I opened up Vim and started to write a simple shell script that would download the proper, extended version of hugo and run it. This is all there is to it:
#!/bin/sh
HUGO_VERSION=${PLUGIN_HUGO_VERSION:-"0.67.0"}
HUGO_ARCH="64bit"
HUGO_URL="https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_Linux-${HUGO_ARCH}.tar.gz"
echo "Fetching Hugo ${HUGO_VERSION} from ${HUGO_URL}"
wget -q -O- ${HUGO_URL} | tar xz -C /usr/local/bin
hugo
This will take the specified Hugo version (or default 0.67.0), download and untar it and run it. That’s all I need.
It does need to be packaged up in a Docker image to be useful with Drone, so I needed a Dockerfile
as well.
FROM alpine:3.11
RUN apk add --no-cache \
ca-certificates \
mailcap \
git \
wget \
libc6-compat \
libstdc++
ADD drone-hugo.sh /bin/
RUN chmod +x /bin/drone-hugo.sh
ENTRYPOINT /bin/drone-hugo.sh
Again, this is pretty straighforward. Use alpine for a small image size, add some dependencies and copy over the shell script.
Using ariejan/drone-hugo#
In your .drone.yml
you can add a build
step. You’ll want to follow that up with something that uploads your HTML files.
steps:
- name: build
image: ariejan/drone-hugo
settings:
hugo_version: 0.65.3
At this time there’s no option to pass along any arguments to Hugo - as I don’t need that. Instead of exposing each option
manually, I’m considering to add a single hugo_args
for that purpose.
You can find the full source and install instructions on github.com/ariejan/drone-hugo.