Skip to main content
  1. Posts/

The Joy of Versioning

·545 words·3 mins·
Nick Dumas
Table of Contents
building-with-bazel - This article is part of a series.
Part 2: This Article

What am I Doing?

Too many times this year I’ve found myself struggling to improve my blog pipeline because I couldn’t keep track of when code stopped and started doing what it was supposed to do. This was entirely my own fault, I was not observing best-practices:

  • I wasn’t using semantic versioning
  • I wasn’t tagging
  • all development happened on main
  • etc etc

All of this worked well enough for private use monoliths, one-offs and skunkworks projects but these Drone pipelines presented a new challenge.

Drone pipelines tend to be structured as a series of docker images operating on a mount that gets injected into all of them so they can share their work. This is fine, docker images are an easy fire-and-forget solution for deploying tools.

As things grew more complex, my sloppy coding practices put me in a lot of unnecessary tight spots.

  • Some parts of the pipeline were idempotent, others weren’t.
  • Some parts of the pipeline were affected by each other’s work. For example, one step scans files for attachments and copies them into Hugo-appropriate directories, and the next transforms links from Obsidian to Hugo layouts.
  • I frequently wanted to implement multiple features/fixes simultaneously but when this took longer than planned, rolling back to a known-good version was impossible because my docker images are only tagged with latest.

All of this added up to things breaking for far longer than they needed to, more often than they needed to. Eventually, enough was enough. I drew a line in the sand and decided that I wasn’t going to live like this anymore.

After some digging I found resources that helped me build a Makefile to take care of things. That first Makefile added a lot but I’m only going to cover the tooling for semantic versioning and git tagging; the rest of that Makefile was go cross-compilation and docker image stuff that I’m replacing with bazel.

To handle automatically incrementing semver values, I landed on bump. Because it’s written in Go, I was able to fork it and patch a few minor issues and make sure that it keeps working for the foreseeable future.

Why does it work?

My current solution relies on a few pieces: bump and my Makefile invoking some git commands.

VERSION ?= $(shell git -C "$(MD)" describe --tags --dirty=-dev)
COMMIT_ID := $(shell git -C "$(MD)" rev-parse HEAD | head -c8)

  go install

bump-major: setup-bump
  bump major

bump-minor: setup-bump
  bump minor

bump-patch: setup-bump
  bump patch

bump is a golang utility that’ll read a git repository’s tags and apply a semantic versioning compliant version increment. bump patch bumps v0.0.1 to v0.0.2. bump major goes from v2.24.5 to v3.0.0. You get the idea.

All together, this suite works perfectly for handling tagging. I don’t have a super rigorous policy on what constitutes a major, minor, or patch version but being able to make bump-patch to tag a specific known-good commit made a world of difference. My drone pipelines became drastically more reliable thanks to version pinning.

But what about Bazel?

Bazel isn’t directly involved in manipulating tags yet. To do that, I’ll need to add bazel build files to the bump repo. I’ll cover that in the next post, where I cover how to use bazel’s stamping funtionality.

building-with-bazel - This article is part of a series.
Part 2: This Article


Beautiful Builds with Bazel
·2681 words·13 mins
bzlmod makes bazel extremely appealing and isn’t hard to grasp for anyone already familiar with go modules. My frustration with make for complex builds led me to bazel.
Validating YAML frontmatter with JSONSchema
·735 words·4 mins
As a collection of Markdown documents grows organically, maintaining consistency is important. JSONSchema offers a way to automatically ensure frontmatter stays up to spec.
Putting Lipgloss on a Snake: Prettier Help Output for Cobra
·900 words·5 mins
Using lipgloss to abstract away the specifics of nice terminal output.