Crystal clear reviews using Conventional Comments
I was at a conference organized by LyonJS where I watched a great talk about code reviews, given by Anne-Laure De Boissieu. Among other things, she talked about Conventional Comments, a way of improving the code review process. I've tested it and I think it's a great approach, so I'd like to introduce it to you.
Although most of you are probably familiar with code reviews, allow me to reintroduce them.
Code reviews have become one of the main activities of software developers. For example, I can spend up to half a day reading the code of my colleagues at Marmelab. This is also a common ground in all Marmelab projects: we forbid the author of the code to merge their own pull request. Every developer must get at least one proofreading of their work before it is merged.
Skipping code reviews may save time in the short term, but it's a big loss in the long run. In my opinion, some of the biggest benefits of this exercice are:
- Promote knowledge transfer and mentoring
- Detect bugs and bad architecture decisions earlier (and you know that it's cheaper to fix mistakes earlier)
- Improve code quality
- Share responsibility within the team
But as always, this is not a silver bullet, as reviews have their drawbacks and can lead to:
- More context switching for everyone
- Frustration for the code author
- Becoming a bottleneck
Conventional Comments are not there to solve all these drawbacks, but to focus on how to clarify communication between developers during the code review process.
You've probably noticed that the name refers to Conventional Commits, and in fact there's a reason: Both aim to have more explicit messages. But Conventional Comments are dedicated to review messages.
I probably won't be a better advertiser than the website for Conventional Comments itself:
Labeling comments encourages collaboration and saves hours of undercommunication and misunderstandings. They are also parseable by machines!
Here's an example of what it might look like in my current project:
As you can see, the message is structured as follows:
<label> [decorations]: <subject>
Only the label and subject are mandatory, the others are optional. A list of predefined labels is provided, which you can use "as is" or create new labels specific to your teams.
Here are a few examples of the labels suggested (in our team, we don't use them all):
The decorations part is a very good idea too, as it allows you to contextualize your comments. For example:
I believe the strength of this approach is that it's very easy to start using, for almost no cost and it brings two essential things:
- As a reviewer, I need to think more carefully before writing my comments to clarify my intent and give an explicit level of concern for each of my comments.
- As the author of the code, the comments are clearer and easier to understand because I have context on the nature of each comment, allowing me to focus on what's really important for the reviewer.
Even if these "pre-formatted" labels seem a little bit inorganic at first glance, I think their use creates a positive feedback loop that leads to better and broader communication within the team.
I probably didn't sell this tool as well as Anne-Laure, but if you're reading this, chances are you'll still want to try it.
If you're using GitHub, the quickest way to get started is to automatically populate saved replies by running this script.
After that, when doing a review, you can load the pre-formatted reply and get a hint on when to use it:
The structured nature of these comments makes them much easier to parse. As described by the official website:
Comments that are easy to grok and grep
I'm not sure what to make of it, But I did look at how I could get comments from Github.
First, you need to install the GitHub CLI on your computer. See the installation documentation.
Then, you can retrieve all the comments of a repository using:
gh api -H "Accept: application/json" /repos/OWNER/REPOSITORY/comments
Or you can retrieve all comments of a single pull request using:
gh api -H "Accept: application/json" /repos/OWNER/REPOSITORY/pulls/PULL_REQUEST_ID/comments
gh api -H "Accept: application/json" /repos/OWNER/REPOSITORY/comments | fx '.map(x=>x.body)' '.filter(x=>x.includes("thought:"))'
Let me know in the comments if you have any interesting use cases!
We've been using Conventional Comments for a week now and feel it's making a positive difference without changing everything and at virtually no cost. We're going to continue experimenting with it, and I recommend you do the same!
But you can get also most of the benefits of code reviews by using pair and/or mob programming, and some teams even use it daily. If you'd like to find out more, take a look at this great conference.