A Drone Hugo plugin that works

Posted:
~700wrds (~3min)

Tagged drone hugo docker

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:

  1. Download the specified versio of Hugo
  2. 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.