Software engineering is not just about writing code and fixing bugs (or dealing with PMs!). Have you ever wondered how modern app development happens? It's not built in a day nor by one person. It's a team effort, often involving collaboration with an engineer who might join the project long after you've moved on or someone who uses your library, whose face you have never seen.
How do you explain to that future engineer why you wrote a particular line of code? Documentation —who keeps it updated? And even if they do, you have to switch tools to read it. JIRA tickets or Asana tasks—what if you're offline or have switched platforms?
Maintaining software sometimes feels like navigating a minefield. Each change or commit is a brand new mine that is easy to trip and explode. Okay, that's an exaggeration. But I banged my head at least a hundred times, trying to decipher confusing code changes, vague commit messages, and broken dependencies.
git commit -m "Short Description" -m "Long Description"
The git commit messages at least solve one part of the problem. A developer can explain what and whys of the change. But let's face it, commit messages like "Fixed Bugs!" which are about as helpful as a one-star Google review with no explanation. (We've all left one of those in a moment of frustration or newbie overconfidence, right?)
Does this sound familiar? The struggle is real, but fear not! In this blog, we'll explore two powerful, somewhat interrelated tools: Conventional Commits and Semantic Versioning, that can transform your workflow into a smooth sailing ship.
But fret no more! This guide will equip you to write clear, concise commit messages that sing the praises of your coding prowess – and even generate changelogs that practically write themselves (let us not get ahead of ourselves yet!)
Conventional Commits:
All it requires for the team is to follow a few conventions, yes it is that simple. Of course, what one writes in the description is still up to individuals, and yes you can still write the notorious "fixed bug!" message. At the end of the blog, I'll share a few resources on how to level up that as well.
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Conventional commits help you categorize your commits into new features, bug fixes, documentation, and more. This instantly provides a clear context for the changes! You begin the commit message with the type of change (as described below), a brief description of the change, and an optional body if you want to dive deeper into the details and reasons behind your changes. Plus, in the footer, you can optionally include your Git issues or Jira task IDs. How cool is that?
Type | Examples | Description |
feat | feat: add new user authentication module | Adding a new feature |
fix | fix: resolve issue with user login | A bug fix |
docs | docs: update API documentation | Document only changes |
style | style: format code according to new style guide | Changes that do not affect the meaning of the code |
refactor | refactor: simplify user service logic | A code change that neither fixes a bug nor adds a feature |
perf | perf: improve database query performance | Code change that improves the performance |
test | test: add unit tests for user service | Adding missing or updating tests |
chore | chore: update dependencies | Changes to the build process or auxiliary tools and libraries |
While you follow these conventions, you'd need to follow a few simple rules to git-commits to completely benefit from this extra work. And the first one of them is "One commit should contain only one change". This rule helps you to keep your code base and commit log both clean.
Semantic Versioning:
With Conventional Commits and best practices for git commits, you can tell the story of your codebase over time. You can briefly explain your choices and guide your successors. But what about the teams that only have access to your public APIs or public library? How would you communicate if the changes in those commits break their systems through no fault of their own?
Almost all of us use some library or framework to build our applications. Sometimes, when we update the code to use a newer version, our codebase breaks. And what if you are building that API or library that millions of people depend on? We don't want to build something that breaks someone's critical application every time we push a change, do we?
Semantic Versioning (SemVer) helps with that. In fact, you might already be using something similar, but this approach makes it more systematic. This method aims to convey the meaning of the underlying changes with each new release. A version number is in the format MAJOR.MINOR.PATCH
, where:
Major Version increments when you make incompatible API Changes.
Minor version increments when you add functionality in a backward compatible manner.
Patch version increments when you add backward-compatible bug fixes.
Examples:
1.0.0
- Initial InstaBudget app1.1.0
- Added new feature to let users add map expenses and bank accounts1.1.1
- Fixed a bug causing double entry for expenses
Till now, we have seen how to be systematic about the way we write commit messages and version our external APIs or libraries that others depend on. We have done all the work; now is the time to reap the benefits of the work you did. Let me introduce you to two libraries that can help you create changelogs automatically. Think of it as a way to generate SemVer from your conventional changelogs.
auto-changelog: A free JavaScript-based changelog generator
Github Changelog Generator: A free Ruby-based changelog generator
https://git-cliff.org: A free Rust-based changelog generator
Commit Lint: A tool that you can integrate into your CI/CD pipeline to lint commit messages and help your team adhere to a commit convention
Commitzen: A command line tool to get instant feedback on your commit message formatting that can be used in place of
git commit -m
Since you stuck till the end of this lengthy blog, here are some more resources that help to level up your commit game.
If you want to learn more about product, technology, software development, and data topics, follow at on my blog or Linkedin.