blog.thms.uk

Blogging with weblog.lol and GitHub actions

My blog is run on omg.lol's weblog.lol service. Weblogl.lol is fantastic product due to it's extreme simplicity.

Until very recently, weblog.lol didn't have support for images, or static assets (such as CSS or JS files), though, so if you wanted those you needed to manage them yourself.

In this blog post I'm outlining how I'm using a GitHub action and the weblog.lol API to manage my blog in Git, rather than through their web interface.

weblog.lol provides a bit of a reference implementation for this. I downloaded the php script referenced in there, and based my implementation around this. However I wanted more features: Specifically, I wanted to manage CSS, JS, and image files all in the same repository.

Pre-requisits

What I want to achieve is the following:

Block storage

Because weblog.lol has nowhere to upload static assets, such as images, CSS and JS files, you'll need to find somewhere to upload these to. I've been using Backblaze B2 for my Mastodon instance and so that was a natural choice. Any other AWS S3 compatible storage would work in the same way, and there are a lot of other options as well.

Git Repository directory structure

This is somewhat arbitrary, but based upon the reference implementation, I decided on the following:

My Workflow

In order to accomplish all of these aims, I've created the following file at .github/workflows/main.yml:

on: [push]

jobs:
  weblog_import:
    runs-on: ubuntu-latest
    name: weblog.lol
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Rewrite references to static assets
        run: php -f script/pre-process.php ${{github.event.before}} ${{github.sha}}
        shell: bash	
      - name: Upload Images
        uses: shallwefootball/upload-s3-action@v1.3.0
        with:
          source_dir: 'images'
          aws_key_id: ${{ secrets.AWS_KEY_ID }}
          aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
          aws_bucket: ${{ secrets.AWS_BUCKET }}
          endpoint: ${{ secrets.AWS_ENDPOINT }}
          destination_dir: 'images'
      - name: Upload JS
        uses: shallwefootball/upload-s3-action@v1.3.0
        with:
          source_dir: 'js'
          aws_key_id: ${{ secrets.AWS_KEY_ID }}
          aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
          aws_bucket: ${{ secrets.AWS_BUCKET }}
          endpoint: ${{ secrets.AWS_ENDPOINT }}
          destination_dir: 'js'
      - name: Upload CSS
        uses: shallwefootball/upload-s3-action@v1.3.0
        with:
          source_dir: 'css'
          aws_key_id: ${{ secrets.AWS_KEY_ID }}
          aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
          aws_bucket: ${{ secrets.AWS_BUCKET }}
          endpoint: ${{ secrets.AWS_ENDPOINT }}
          destination_dir: 'css'
      - name: Import weblog
        run: php -f script/import.php nanos ${{ secrets.WEBLOG_API_KEY }} ${{github.event.before}} ${{github.sha}}
        shell: bash	

So, let's run through what this script does:

Every time I push any changes to GitHub, the following actions will be performed:

  1. We firstly check out the latest version of the repository.
  2. Then we run a script, located at script/pre-process.php. You'll find a full copy of that script below, but here is a summary of what this script does:
    1. It firstly calculates md5 hashes of all images, CSS, and JS files.
    2. It then gets a list of files that have changed in this push.
    3. For each changed markdown or html file, it replaces relative references to the static files with absolute references, including the md5 hash, calculated earlier. E.g. if I have authored a post with ![Image](․․/images/image.jpg), this will now be referenced as ![Image](https://media.thms.uk/images/image.jpg?v=0800fc577294c34e0b28ad2839435945) It also does the same for all my templates (regardless of whether these have changed or not), simply because I frequently change my CSS/JS files without touching the templates. So these get synced with every push, regardless of necessity.
    4. Finally, it deletes any unchanged CSS, JS, and image files. Why? well, because we are going to upload all files in the images, css, and js directories to B2, and we don't want to upload unchanged files over and over and over again.
  3. We upload any images, JS, and CSS files to B2
  4. Finally run a script script/import.php, which will import any changes into weblog.lol. I'm mostly using the provided reference implementation here, though I've removed some bits and pieces. Again, you'll find a full copy of this script below, but here is a summary of what it does:
    1. It again gets a list of files that have changed in this push.
    2. It then adds files that were changed by the pre-process.php script (mostly the templates).
    3. Finally, it simply submits all changed files to weblog.lol's API

Summary

So that's how I write this blog. I enjoy authoring in my local text editor much more than in the weblog.lol interface, among others because I use VS Code, with the Markdown preview built-in, so I get live previews while authoring.

The Scripts

This is my pre-process.php script:

This is my import.php script: