How (and Why) We’re Standardizing Our Commit Messages
Have you ever tried to debug a production issue by looking at your commit history, only to find a bunch of commits that don’t seem to be connected to any specific feature? Or maybe you've pulled the latest version of a dependency and noticed a bug that wasn’t there before?
It’s hard to pinpoint where a problem might have begun if your project (or its dependencies) don’t rely on standards to commit and release code. This was a problem I set out to tackle in my organization: How can we make it easier to understand how our repositories change over time while minimizing disruption to engineers’ existing workflows?
Why We’re Introducing Commit Standards
At Alto, we value effective communication. We keep our pharmacists and operations team in the loop about every new feature we release to production on a daily basis. We also announce changes to our codebase in a dedicated Slack channel to keep our engineers informed. But that raises the question: How do we ensure that someone doesn’t forget to make an announcement? And can we reduce the time we spend writing one up? Introducing a commit standard would enable us to use automated tooling that makes communication about code changes effortless.
Consider an open-source repository with hundreds of contributors. Project owners often adopt standards and industry best practices because it makes the project easier to maintain as the number of contributors increases. Eventually, our engineering team will grow to this point—and, just like in an open-source project, we can’t expect engineers to retain all of our conventions in their heads when they contribute. Standardizing commit messages eliminates one of the many variables around how we commit code. It can give engineers more confidence in their releases, build trust in our codebase, and increase productivity.
Finding Support for the Project
Many engineers have a distinct working style. If you propose a change to their everyday workflow, you will likely encounter some resistance. That’s why identifying and working with key stakeholders before you introduce a new process can help ensure its success. One way to do this is to chart stakeholders on two axes—influence in the organization and interest in the project:
I used this chart to decide how I would direct my communication with the team. Folks who fell into the “low influence” and “low interest” quadrants didn’t need to be involved in the whole process. Instead, I kept them informed by using project-specific slack channels and documentation in Notion to communicate status updates and summarize meetings. Topics that required a team decision were discussed verbally rather than using Slack to avoid potential miscommunications.
The more likely someone was to push back on the project or give me valuable feedback, the more involved they were. I included those who fell into the “high influence” and “high interest” quadrants in almost every meeting. These folks served as a kind of litmus test for my ideas. They typically had high standards and expectations and needed to be convinced that a change was worthwhile if they were going to get behind it. Keeping people like this involved in the discussion is a great way to ensure that your initiative will produce value for your organization.
Taking the First Step
In a perfect world, we’d have standardized commits in every repository. However, given that Alto is a fast-moving startup, foundational changes need to be rolled out incrementally to minimize churn, validate impact, and allow us space to learn and iterate. There’s often not enough time or resources to do everything, and going all-in on something may require more effort than it’s worth.
We began by identifying the knowledge gaps we currently have about commit standardization and how we could iteratively validate the required process changes. We initially considered beta testing with the production app that runs our day to day operations because it had the most contributors and the most to gain from standardization. However, we didn’t want to risk blocking the majority of our team or experimenting with a project that was critical to business operations. The next best option was our internal component library—it had fewer contributors, so fewer engineers would be blocked if something went wrong, and more projects depended on it, so the potential impact would still be significant.
Given that one of our company values is to Focus On Impact, and that internal changes like this are difficult to measure, we quantified our level of success or failure using a team survey. We sent out a series of questions at the start of the project asking the team to rate their satisfaction with our current commit, review, and release processes. We plan to compare these results with a follow-up survey to measure changes in ease of committing code, confidence in releasing, and our developer NPS.
Evaluating Our Options
After closing our knowledge gaps and getting a baseline understanding of how the team felt about our release processes, we decided to adjust the scope to include the following changes:
- Commit Standardization (i.e., formatting and enforcement of commit titles)
- Versioned Release Automation (i.e., automatic version cuts, changelogs, and notifications)
We looked toward existing open source solutions to make these changes because we were on a tight schedule. There were many options to choose from, so narrowing them down to a shortlist before presenting them to the team helped speed up the decision-making process. The best tools for the job will depend on your engineering organization, of course, but we prioritized maturity, flexibility, and compatibility with our existing workflows during our evaluation.
Here’s what we considered:
We landed on the Conventional Commits standard because it has been vetted and used extensively in other projects, and a whole ecosystem of release tooling has been built around it. It also has a short learning curve, is flexible enough to work with all our repositories, and only enforces the bare minimum necessary to generate semantic versions based on commit titles.
We chose Commitizen to help engineers get familiar with the new standard, Commitlint to warn about (but not block) contributions with invalid commits, and Semantic Pull Requests to serve as the final gate for validating commit titles. This way, non-standardized commits are only stopped from being merged when a pull request is made, and it can be easily corrected using the GitHub UI.
Versioned Release Automation
The open-source tooling for release automation was sparse and highly specialized, but we found Semantic Release to be the exception as it offered the most mature, flexible solution. It manages everything from cutting a release to generating a changelog to publishing packages and notifications. It also isn’t limited to only publishing NPM packages, making it an excellent fit for our multi-language codebase.
While we have a ways to go before versioned releases are automated in all of Alto’s repositories, we’ve made a significant first step with commit standardization. Some engineers have already proactively adopted the new standard without any tooling, and I’ve personally found that it has helped my commits stay focused and become more granular.
So far, we’ve standardized our component library. The commit history in this repository used to look like this:
And now, it looks like this:
Commits now have more context in them that’s visible at a glance (e.g., feature vs. fix), and breaking changes are explicitly noted in the commit message using an exclamation point (e.g., refactor!). These commit titles are used to automatically generate a changelog any time we cut a release. We can even automatically cut and version-bump a release for every new commit because we follow a commit standard.
The next phase of this project will be to review and act on the feedback from the follow-up survey. We will continue to build on top of these standards with release automation tooling and discuss what process changes make sense for the rest of our codebase. We are confident that through these changes, we will be able to de-risk code contributions, reduce the burden of cutting a release, and better prepare for our engineering team’s future growth.
If you have any questions about Alto, or are interested in joining our team, please reach out via LinkedIn.