Maximize your code review process

How to focus on code collaboration rather than code approval.

Sarah Horan Van Treese
The Startup
7 min readApr 20, 2020

--

Photo by NESA by Makers on Unsplash

Poorly defined code review processes can cause bottlenecks that greatly impact time and effort on a project, and anything that negatively impacts time and effort on software delivery tends to result in a vicious self-feeding cycle of negative perceptions and reduced value.

Code reviews are consistently one of the most predictable areas where tensions surface, either with other team members or with the process itself. Particularly when teams are working individually on assignments, rather than pairing or collaborating throughout, or when codebases are owned across teams that don’t work closely together, code reviews are essentially asking your peers to give up their valuable time to constructively critique the work you’ve put your valuable time and effort into. Constructive criticism is sometimes difficult to take; opinions don’t always align; and to top it off, everyone involved is likely under pressure.

The key, then, is to make sure to reduce time-waste and you are maximizing the value you get out of them.

Code Approvals = Bottlenecks

Problematic code review processes are familiar and easy to spot, and, more often than not, stem from the same issues.

Signs you might be setup for “code approval bottlenecks”:

  1. You have a few “senior” engineers who are responsible for many code reviews OR you have engineers responsible for code reviews on work that they are not actively involved in delivering.
  2. Engineers work on tasks in isolation and wait to engage peer review until what they think is the very end of their work.

If you used a Kanban board, it might look something like this. In most cases, you don’t need to look to the Kanban board to see it though because it’s likely a hot topic in standup meetings as well.

When code review processes aren’t going smoothly, it tends to look something like this:

  1. Reviewers get slammed with a bunch of large code reviews (ahem, code approvals) at once, often toward the end of a sprint.
  2. Reviewees move onto something else while they are “waiting on code review” for their last story.
  3. Because reviewers are juggling multiple reviews and/or because the reviews are large, it takes time to get through them, particularly since they are likely juggling these with their own deliverables.
  4. One (or both!) of a few things happen: a) reviewers feel pressured to rush the review and therefore provide minimal feedback and/or b) reviewees are rushed to respond to feedback at the end of a delivery cycle or sprint.

Cycle time increases with a lot of “hurry up and wait” in your dev cycle, with lengthy feedback loops and a lot of context-switching. Code reviews feel more like bottlenecks than improvement opportunities, and the result is frustration and a lot of potential value lost.

Ideally, you want to move away from “code approvers” and toward “code collaborators.” Ask yourself what you think you are solving with “code approval” and whether there are ways that you could better structure collaboration to meet the same goal. In fact, the most ideal way to get the value out of your code review process is to find alternative collaboration methods that eliminate the need for code review altogether! But, depending on your organization, that might be a pretty big shift. In the meanwhile, here are some steps you can take to get collaborative value out of your code reviews.

It’s all about collaboration and expectation-setting.

At a high level, the same edicts that apply to establishing high-value code review processes are those you’d apply to your agile processes and practices, CI/CD, testing practices, or process improvements in general:

  1. Look for ways to add the right value at the right time.
  2. Automate anything you can.
  3. Aim for the quickest feedback loops.
  4. Work in small batches.
  5. Collaborate as a team!

Focus on continuous review.

Aim for Continuous Review and embrace the idea that two (or more) heads are greater than one and reviewer feedback should contribute to the work in progress.

Think of the value similarly to the value from pair programming:

  • Increased quality
  • Increased knowledge share

Lean into synchronous approaches to review and collaboration.

In other words, don’t try to use async code reviews as your sole approach to code collaboration.

Pair programming can be a particularly effective technique to get feedback and “continuous peer review.” Many teams view it as an alternative to PR-based code reviews altogether. I don’t think it needs to be an “either/or” scenario. I personally think that two minds together can still share the same kind of tunnel-vision that a fresh set of eyes can help uncover; even after really productive pairing sessions, I’ve seen value in getting review from a separate team member. Instead, look for as many ways as possible to increase ongoing review and collaboration — such as pair or ensemble programming — and then use asynchronous code reviews to augment and fill in gaps rather than as the sole means of peer review and collaboration. If your organization or team doesn’t support pair programming, early-often code reviews can be a great alternative to get ongoing collaboration.

Stop using the word “approval” or “approver” to describe your process.

Words reinforce team conceptions. If you’ve been operating with a “code approver” process for a long time, it might be hard to get this out of the team vocabulary, but it can be helpful to commit together to reframe it as “review and collaborate.” Even when your process requires an “approver” before merge, reframe how you discuss that activity as a first step toward finding ways to eliminate that need. Even if you never remove your branch “approval” policy, a team which thinks of the activity as a collaborative effort is less likely to approach it as an async handoff, which will help reduce the impacts of bottlenecks.

Foster a culture that sees collaboration as part of contribution.

In team cultures which have emphasized individual contributions, this can be a big culture shift. Code reviews can be a stepping stone toward that mindset shift if you emphasize the value of the collaboration to all parties involved and equate it on part with that of the coding contributions.

It’s a self-actualizing loop: as reviewees start to see value in the feedback they are getting, they are more likely to seek it as a benefit and to seek it earlier and more frequently; likewise, reviewers begin to feel ownership in the code being reviewed when they recognize that their contributions to code reviews are, in fact, contributions to the deliverable.

If your team isn’t ready to move away from assigning individual tasks, then a first step is to at least make sure to allocate time for code reviews for the reviewers.

But there’s another crucial aspect to making this successful, and it goes beyond time and scheduling: code reviewers need to feel that their contributions to code reviews are viewed on par with their tasks they have been individually assigned. If any part of your system, explicitly or implicitly, rewards coding over collaboration, you will never get past your “code approval bottleneck.”

Let’s say Sally codes 4 features individually (her assigned tasks) and collaboratively contributes to 3 other features (via code review, pairing or both), whereas Jane codes 5 features but collaborates on no other features. Be honest: would your company or team (whether implicitly or explicitly) view Jane as having been the higher contributor? The reality is that Sally contributed to 7 features; if your culture views otherwise, collaboration and peer review will always be deprioritized. This view — that individual coding tasks are the best measure of contribution — is one of the reasons that many organizations resist adopting team-focused contribution and collaboration techniques. Code reviews are a great first step toward fostering that collaborative mindset, but you can only get there if you don’t disincentivize it by focusing on individual contribution of code. In organizations where this mindset runs especially deep, you might want to consider ways to “make the code review work visible” as a way to start to shift the mindset.

As you gain momentum on the value of collaborative delivery, continually ask yourself, are code reviews still the best way to facilitate this collaboration?

Add the right value at the right time.

Early collaboration on work is incredibly valuable, and sometimes the easiest way to communicate about code is, well, through code itself. Directly pairing is the most straightforward way to get that early collaboration, but in scenarios where pairing isn’t an option, “draft” PR’s can be a great way to do that.

But…make the expectations clear and include collaborators who understand that early collaboration is the expectation. I’ve frequently seen reviewers get frustrated by being pulled into code reviews that they feel aren’t yet ready for review, particularly for reviewers who are responsible for a large number of reviews. As I mentioned, the real root cause to solve there is to eliminate the need for reviewers being responsible for a large number of reviews on work they aren’t collaborating on. But when your org isn’t “there yet”, consider using different code reviews at different stages of development to facilitate different audiences and goals.

If the tools your team uses don’t explicitly support the concept of “draft pull requests,” establish team conventions for “drafts” which could be as simple as prefixing a PR title/description with “DRAFT.”

Automate anything that can be automated.

Many source control providers allow for triggering builds from Pull Requests to provide pre-commit validations.

Baking automated validations into the PR’s can have huge benefits to cycle time; reviewers can focus can be on adding value that cannot come from automated validation.

When you come across similar feedback repeatedly, consider whether it is something that could be coded into an automated validation rather than relying on team members to catch during review.

Last but not least…address code review processes in retrospectives and continually adapt team guidelines.

Everyone on the team should feel invested in continually improving. Make a point of consistently getting feedback from the team and adapting your process to continually add maximum value. What works best today may not be what works best tomorrow, so don’t assume that getting it right means never addressing it again in the future.

--

--

Sarah Horan Van Treese
The Startup

Software Architect, DevOps and Software Engineering Leader