A few months ago, one of my colleagues posted on our internal engineering slack channel about behavior he had noticed in a pull request he reviewed.
I love a great PR description, and this one is amazing. Has all the good stuff – why the work is being done, the high level changes, how it relates to existing work in the project, and a self-review.
This was an off-the-cuff remark about some great work that was done, but stood out for two reasons to me. It clearly identified what was great about the PR that was submitted, but also basically outlined a rough checklist of what made it so great. As an engineer who reviews a decent amount of code, I expect all PRs that I review to have at a minimum a brief description of the updates to the codebase and identified changes in behavior. What this engineer included in this specific PR that isn’t widely done was context building as well as a self-review.
We all know the basic requirements of a pull request- not massive (please no 5000 line PRs), a link to your Jira ticket, test plan etc, but what I think is often missed is sharing why you’re doing the work you’re doing and creating documentation for future readers. This might sound like a difficult thing to do, but it’s easy when you get the hang of it. Here at NerdWallet we call this process self-reviewing.
So what is a self-review?
A self-review is a process you, the code-writer, go through AFTER writing your code and before you’ve opened up a PR for review. If you’ve ever gone through the process of a code walkthrough, this is the same sort of thing, but it’s done asynchronously. You walk through your changed code on Github/Gitlab and leave comments on the actual code, describing the decisions that were made, any ‘gotchas’ or behavior not captured with a simple code-diff, and any other context you want to share.
This self-review can contain things about why you chose to use a certain return value or naming convention, or how you expect the code to be used. It can include links to outside documentation, other pull requests, Jira tickets, or slack conversations.
The self-review is largely for your peers, but it’s also useful for you as the author. It forces you to be mindful, and take the time to walk through the code you’ve written. There have been numerous times where I’ve written code, been ready to open the PR, but upon self-review, realized I did something dumb and needed to correct it.
I’ve already said a lot of this above, but I see self-reviews as important for several reasons:
- First and foremost, they make code-reviews faster. Everyone usually has a few PRs they’re on the hook to review, and the faster I can get through them, the more time I have to focus on my personal work. My team practices round-robin reviews (a great tool for preventing siloing of knowledge, but also spreading the load of reviews), so we don’t all necessarily know what all the context is that goes into a PR. A good self-review means that I spend way less time getting up to speed on what is going on with the pull request that comes across my desk.
- They force you to practice mindfulness. A self-review is something that will take time, and force you to pause and consider the work you’re asking to add to a code base. It’s a great opportunity to pick through the code you’ve written and ensure it’s logical, cleanly written, and actually accomplishes the objective of the work needing to be done.
- They make it easier for (future) you and your (future) peers. Similar to point #1, how often do you come back and look at some code and wonder “what on earth was I trying to do here?“. I am a big fan of looking through code and walking back through its history to see how it changed. Part of this involves looking at the pull requests and comments that generated the code. If you are able to capture the context of why and what you were doing in a PR, that makes understanding the history of a codebase so much easier.
- They help enforce code standards and high quality code. Tangential to the above, taking the time to do a self-review presents an opportunity to catch things like syntax errors, anti-patterns, and code smell. It’s a lot easier to deal with these things before you merge code into the codebase. A self-review oftentimes will allow you to catch these things early on.
- They help with creating a remote-friendly workplace. This might sound counterintuitive, I know. Consider how software engineering, and business in general, has changed post COVID. My entire team is remote: we have employees in the eastern US, some in Canada, one even in Hawaii. The vast differences in time zones coupled with flexible work schedules means there is not a ton of time where folks can reliably meet to do in-person code reviews. Doing a self-review cuts down on the number of times we need to schedule a meeting for a code review- instead, it means the work of this review can be done largely asynchronously, with us only meeting if there’s a question that we can’t answer through comments.
It’s important to note, self-reviews do not replace well commented/self-documented code. They should be used in conjunction with smart variable/method names, logical code, and appropriately placed in-line comments. Code comments and READMEs are useful for future readers and it’s safe to assume that people will seek them out- if there’s something critical to share for future readers, include it both in your self-review but also the code itself.
On my team, we now have ‘self-review completed’ as a requirement on every PR; while it may take a few extra moments, it’s been recognized as a great behavior and best-practice. I’d encourage you to try it.