Skip to content

Dispatches

Conventional Commits: How to Write a Better Git Commit Message

If you browse the commit history of a long-running project, you will find one of two things. Either a history that reads like a record, something you can actually use to understand why the code is the way it is, or something like this:

fix stuff
wip
update
changes
more fixes
actually fix it this time

I have written commits like that. Most developers have. It happens when you treat the commit message as a formality, when the only audience you are writing for is the CI system that just needs to see something in the message field.

Compare that to this:

feat(datastore): add support for datastore clusters
fix(ssh): prevent IPv6 addresses from being double-wrapped in brackets
refactor(firmware): set firmware configuration during create
chore(deps): bump govmomi from 0.51.0 to 0.52.0
docs: update README with plugin installation instructions
feat(datasource): add virtual machine datasource

Which would you rather read?

The second log follows Conventional Commits, a lightweight specification that gives every commit a predictable, parseable shape. The difference is not talent or effort. It is convention.

This post is my attempt to explain how Conventional Commits work, why each rule exists, and how I use them in practice. A lot of this builds on Chris Beams's foundational piece, How to Write a Git Commit Message. If you have not read it, do that first. What follows extends the principles he outlines into the structured format I have settled on.

Inside the Stack: How This Blog Is Built

Every once in a while, someone asks me how this site works. The short answer: it is a static site generated by MkDocs, themed with MkDocs Material, deployed to GitHub Pages via GitHub Actions, with Cloudflare Pages serving pull request build previews and Cloudflare handling DNS for the custom domain. No CMS, no database, no runtime server. Every page is a Markdown file in a Git repository. Everything runs automatically on every push to main.

This post walks through how all those pieces fit together, with the actual configuration files that run this blog today.

CONTRIBUTING.md: Writing Practical Contribution Guidelines for GitHub Repositories

Every open-source project on GitHub eventually reaches the point where someone outside the immediate author wants to help. They open an issue that is missing half the information needed to reproduce it. They submit a pull request on the main branch that touches a dozen unrelated files. Or they send a message asking where to start.

A well-written CONTRIBUTING.md is the answer to all of those situations before they happen. It is the first thing a potential contributor reads when they want to get involved, and it sets the tone for every interaction that follows. Done right, it reduces back-and-forth, keeps the project moving, and signals to contributors that the project is organized and worth their time.

This post walks through how I write CONTRIBUTING.md files for my open-source projects: what goes in them, why each section matters, and how to write guidelines that contributors will actually follow.

Use Task in GitHub Actions with tenthirtyam/setup-task

If you have been using Task (go-task/task) as your task runner and build tool, you have probably run into the same friction I did: getting it installed cleanly inside a GitHub Actions workflow is more annoying than it should be. There is no native support on GitHub-hosted runners, so you end up writing a curl one-liner, hand-rolling a cache step, or copy-pasting boilerplate across every workflow in every repository. It works, but it is not great.

tenthirtyam/setup-task is my solution to that problem. It is a purpose-built GitHub Action that handles downloading, caching, and configuring Task in a single step so you can get back to what actually matters: the tasks themselves.

Announcing the Packer Plugin for VMware Desktop Hypervisors v2.0.0 Release

I'm incredibly excited to announce the v2.0.0 release of vmware/packer-plugin-vmware.

This isn't just an incremental update; it's the culmination of months of dedicated effort to refactor, modernize, and refocus the plugin for the future.

Additionally, this is the first release of the plugin after the transfer of the project to Broadcom under the vmware GitHub organization.

🚀 Redefining the Plugin's Mission

The first and most significant change is a decision to refine the plugin's focus. Moving forward, the plugin will exclusively target the VMware Desktop Hypervisors: VMware Fusion Pro and VMware Workstation Pro.

For a long time, the plugin carried the maintenance burden of supporting VMware ESX. While this was useful in the past, the ecosystem has evolved. Broadcom provides the feature-rich Packer Plugin for VMware vSphere vmware/packer-plugin-vsphere which is purpose-built for vSphere environments. Continuing to maintain parallel ESX support in this plugin created a confusing user experience as well as split or duplicated development focus. By removing it, efforts will be dedicated to creating the best possible plugin experience for the desktop hypervisor user base.

Similarly, support is removed for the Workstation Player which has reached end-of-availability.

This sharpened focus is the bedrock upon which the release is built, enabling a more stable, feature-rich, and maintainable plugin.

Enhancements

The release will introduces some highly requested features that unlock new and more efficient workflows.