brandonllocke

How This Blog Gets Built

As is trendy among tech folks at the moment, this blog is nothing more than static html files. Each post is a single markdown file that gets “built” into a blog and deployed via a set of scripts. Lets break down this process. Maybe you’ll find it useful for one of your own projects.

Background

This blog is built with Hugo, a super fast static blog creator. I’ve intentionally kept this site small and simple. It certainly passes the requirements for the 512KB Club, though I haven’t submitted it for inclusion. I’ve intentially included no tracking/analytics on the site. I don’t know that you’re reading this right now. Other pieces of software involved are git, gitea, and Drone, though I would love to look into Woodpecker CI as it is the open-source fork.

Git and Gitea

First and foremost, all of these articles/posts/blogs are kept in a git repo on my laptop and mirrored on a Gitea instance that I host inside my local network. This instance is not available outside of my home network, which does limit where I can post to some extent (there is always SSH though). Adding a new article is a simple as adding a branch, writing the article, commiting it to the repo and creating a pull request in Gitea.

The Pull Request

You’re likely asking, why the pull request as you’re the only one working on the repo? Simple. It’s part of the process. Once a pull request is created, Drone kicks into gear and runs a build of the content. Should this build fail, Gitea will warn me of this failure. If it should succeed, Gitea will tell me that too. As a step of this build, Drone sends the completely built site to a server on my local network that makes the site available to me via Apache. This is a place for me to double check that everything looks right before merging the pull request.

The Merge

Just like with software, once everything is in order, I want to merge the new article into the rest of my build. This is as simple as hitting the button in Gitea. In turn this kicks off another build via Drone that runs the build again, fresh, and then uploads it to its final resting place on my hosting server.

My .drone.yml File

This file lives in my git repo and essentially tells Drone what it should be doing and when.

---
kind: pipeline
type: docker
name: default
trigger:
  branch:
    - master

steps:
- name: Version check
  image: peaceiris/hugo
  commands:
  - echo "Checking Hugo version."
  - hugo version

- name: Build
  image: peaceiris/hugo
  commands:
  - hugo --destination /drone/src/build

- name: Local-upload
  image: ogivuk/rsync
  commands:
  - eval `ssh-agent -s`
  - echo "$SSH_KEY" | ssh-add -
  - mkdir -p ~/.ssh
  - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
  - rsync -rv --delete -e "ssh -p {sshport}" /drone/src/build/ root@{mylocalserver}:/var/www/html/ --checksum
  environment:
    SSH_KEY:
      from_secret: drone_ssh_key
  when:
    event:
      - pull_request
    action:
      - opened
      - synchronized

- name: Remote-upload
  image: ogivuk/rsync
  commands:
  - eval `ssh-agent -s`
  - echo "$SSH_KEY" | ssh-add -
  - mkdir -p ~/.ssh
  - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
  - rsync -rv --delete -e "ssh -p {sshport}" /drone/src/build/ {mywebhost}:{path/to/my/website} --checksum
  environment:
    SSH_KEY:
      from_secret: drone_ssh_key
  when:
    event:
      exclude:
        - pull_request
    action:
      exclude:
        - opened
        - synchronized

The first two steps Version check and Build run any time there is a change to the master branch of the repo. This is generally only when there is a new pull request created or a merge is happening.

Notice that the Local-upload step only runs when a pull request is opened or synchronized, that is, the task will rerun whenever a new pull request is created or if a pull request is updated with an additional commit. This is great for when I need to make an edit to an exisiting article but I still want to double check the output of that article before merging.

The Remote-upload step runs when anything else on the master branch happens. This is generally just when a pull request gets merged as I don’t generally commit direcrtly to master (though I could, if I wanted to).

Additional resources on how to setup and run Gitea with Drone CI: https://docs.drone.io/server/provider/gitea/

I use the official Gitea and Drone docker images.