Publishing a website on Fastmail - Part II

Posted on Jan 12, 2026

The fantasy was simple: write a post, push to GitHub, and watch the blog rebuild itself like a phoenix from Markdown. The reality? CI pipelines are just slow-motion debugging sessions wrapped in YAML.

First Attempt: WebDAV or Bust

Fastmail supports WebDAV. Which is like FTP’s awkward cousin. My thinking was: write a GitHub Actions script to build the site, then push the generated files to Fastmail’s WebDAV endpoint. In theory, clean. In practice, cursed.

What I Tried (Spoiler: It Didn’t Work)

I started with this:

- name: Upload Hugo site to Fastmail (via curl + WebDAV)
  run: |
    BASE_URL="https://webdav.fastmail.com"
    find public -type f | while read -r FILE; do
      REL_PATH="${FILE#public/}"
      curl -T "$FILE" -u "$FASTMAIL_USERNAME:$FASTMAIL_PASSWORD" "$BASE_URL/Sites/blog/$REL_PATH"
    done

It uploaded… nothing. Fastmail’s WebDAV is picky. Sometimes it 200s you into thinking things worked. Sometimes it silently drops your files into the abyss.

Second Attempt: Let’s Try rclone (lol)

I figured: why handcraft when someone else already built the spaceship?

- name: Install rclone
  run: curl https://rclone.org/install.sh | sudo bash


- name: Configure rclone
  run: |
    mkdir -p ~/.config/rclone
    echo "[fastmail]" > ~/.config/rclone/rclone.conf
    echo "type = webdav" >> ~/.config/rclone/rclone.conf
    echo "url = https://myfiles.fastmail.com/" >> ~/.config/rclone/rclone.conf
    echo "vendor = other" >> ~/.config/rclone/rclone.conf
    echo "user = $FASTMAIL_USERNAME" >> ~/.config/rclone/rclone.conf
    echo "pass = $(rclone obscure \"$FASTMAIL_PASSWORD\")" >> ~/.config/rclone/rclone.conf

Only to be greeted with this beauty:

CRITICAL: Failed to create file system: couldn’t decrypt password: input too short

The password wasn’t available at the time rclone obscure ran. Rookie mistake. Environment variables weren’t interpolating properly in GitHub Actions.

Third Attempt: Just Build the Site

Before I went down another rabbit hole of deployment, I stopped to ask: is Hugo even building the site?

Turns out, it wasn’t. I’d forgotten to include the theme download step. So hugo –minify was silently failing because there were no layout files. No warning. No build.

Once I added:

- name: Download Ananke theme
  run: |
    mkdir -p themes
    git clone --depth=1 https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke

…it actually worked. The public/ directory came to life.

But I was still stuck on deployment.

In Part III, I’ll show you the working version. The one that builds cleanly, uploads cleanly, and requires zero human intervention. We finally defeat WebDAV. Or at least learn to coexist.