Daily Code Reviews as a workflow
Make code reviews a part of your daily routine and see the quality of your software improve and your team’s efficiency and motivation go up at the same time.
Why do code reviews at all?
The main idea behind code reviews is to ensure code quality. As a developer, having your implementation reviewed by a teammate may help in a variety of ways. It can identify errors and bugs early on, address possible performance issues, help you learn from each other, and much more. It is a powerful tool, which all teams should use.
It is an easy step to add to our workflow, but how can we make sure to get the most out of it? How not make it feel like a chore or a waste of time, which we would rather spend implementing the hot new feature?
On our team, we deal with tasks that range from a few hours to several months in engineering time. Until recently, we approached them all the same way in terms of workflow, which in its simplest form looked somewhat like so:
- one or several developers would pick up a task, divide it between each other and get cracking,
- as soon as someone was done and happy with their part of the implementation, they would create a pull request and send it to code review,
- upon approved pull request, QA would take over and run a set of test cases,
- when resolved by QA, it would get scheduled for release.
Anyone who is familiar with such a workflow, is likely to be facing the same problem as we did — several days’ worth of work generated a PR of a magnitude that was difficult and tedious to review and made it impossible to preserve all the great benefits of the code review process mentioned earlier. The majority of our code reviews for big tasks, which most of the time are new features, presented themselves to be too complex and did not bring any value.
In an attempt to address the problem, we would usually start with the obvious and split up the large projects into subtasks, phases, parts, stages… No matter what we called it, we struggled with finding a way to review each others’ code in a manner that brought value. We kept finding ourselves in a situation where opening a PR meant facing something like this:
So you are supposed to review over 100 files. What do you do?
A. The ambitious Adrian.
Adrian brews a cup of coffee and sets on a long journey of reviewing the whole thing in detail. He generates a lot of comments, which means more time to spend on resolving them later. The author is blocked while waiting for review. Adrian spent the whole day without producing anything of his own, which made him feel like he did not accomplish anything.
B. The eager Betsy.
Betsy jumps into it full of energy. She makes valuable comments and gives priceless suggestions. Six files into the review, she gets bored and skims through the rest. The author is happy with the comments received and learned something new. All seems great, apart from the other 90% of the code, jealous of the love and attention given to the first few files. Wasted opportunity and lots of code never reviewed.
C. The trusting Carlo.
Carlo looks at the PR, scrolls through the files once, and tries to beat his time in the second pass. He tells himself that implementation is “probably fine”, gives it +1, and moves on. The author can deliver, and Carlo had a productive day of his own, yay! They will meet again when fixing bugs in the very same code.
Alright, joking aside, my point here is, of course, that there is no correct way of reviewing over 100 files. No matter how you approach it, you miss out on some of the benefits of code reviews or ruin your workflow. Issues in implementation are bound to get missed, knowledge sharing is limited, and people are bored. We wanted a better way.
To solve this problem, we tried a rule of Daily Code Reviews (DCR), which was eventually permanently incorporated into our workflow. The idea could not be more straightforward and has just two steps:
- Always start your day with code reviews.
- Always finish your day by making a pull request.
That is it!
We only expect each other to follow common-sense rules like keeping the PRs focused on a single problem with an easily definable scope and make sure they are well described. In practice, they contain a small part of a long-term task the developer is continuously working on and could finish in one day. A big part of DCR is that due to the limited time of a single workday, it naturally enforces reasonably sized PRs. It may sound like a lot of work to add to your daily routine, but it is not unlike any other good practice, which takes a bit of time to get used to. Once you do, it just makes sense.
Surely, skepticism is kicking in, and doubts are popping up — Will it not take too much of my time? How can I possibly have something ready every day? Does it limit my flexibility? There are many valid concerns, so let me go through what we kept in mind as the most consequential risks and how they turned out in practice.
Prolonged engineering time?
We work with deadlines and are expected to match time estimations. Spending time on pull requests and code reviews every day over a few weeks could significantly increase development time.
To ensure that our efficiency is not affected, we compared how well our estimations match the actual engineering time. Several months’ worth of features gave us an amount of data we were comfortable trusting. In the end, our engineering time has not seen a significant change at all, but it has become more predictable. Now, our estimations are spot on most of the time, which makes tasks easier to plan.
Time wasted on refactoring?
Code reviews contain comments and requests for changes. That could slow down the process by having to address those daily.
Applying the new workflow has changed the way we look at refactoring. Instead of waiting until the implementation of a new feature is complete, we can apply small refactoring tasks along the way. There is no need to restructure large amounts of files at once at the end of development and risk breaking the existing business logic or design patterns.
Blocked by pending reviews?
We are all busy and may have slightly different schedules. Waiting for yesterday’s code to be reviewed may be stressful and get in the way of carefully planned tasks.
Yes, you may occasionally need to wait for a review because your colleague overslept that day. To deal with such situations, we have structured a simple system that deals with managing branches and pending code reviews.
As you start working on a task, you create a main branch. For the first pull request, you branch out of the main one. In case it is reviewed by your teammate in good time, you merge it and branch out again for your next PR. Otherwise, you branch out from the latest branch and continue from there. Eventually, you may be working with a chain of branches (we usually suffix them with a PR number) that can be later merged all the way back to the main.
Having to pick a small part of the task may not be easy. It could make you miss the big picture and have to refactor even more.
Being restricted to a narrow scope every day may seem like a concern. What we have learned was that this became possibly the greatest benefit of all instead. The restriction of DCR forces a developer to extract a problem that can be resolved within a day. If you divide a large complex project into snack-able bites, you give each of them the attention they deserve.
One important note to remember about DCR is that it represents a workflow strategy rather than a strict requirement. The aim to make a pull request by the end of each day ensures optimal scope size. However, the amount of hours of work that go into writing i.e. 50 lines of code, is not always the same. It is not uncommon to produce no lines of code at all on the days we focus on architecture and planning. Thus, DCR should not be considered too literally.
We concluded that there were no reasons to worry about the concerns we had. But a new workflow should also bring new value. Here is where DCR particularly shines. Now, we can read through them in their entirety and use the various benefits and possibilities they offer — produce good code, learn from each other, plan better, and much more. Let me elaborate on what we appreciate the most.
Code reviews are thorough and bring great value.
Before DCR, our code reviews were useless. We turned it around completely, and they are now one of the most prominent stages in our development process. When reviewing code, you get to see the full scope, understand the code, learn new ways and make educated suggestions and comments. And as the author of a PR, you receive the feedback you need to improve your code, grow your skills and make sure you are on the right track.
Architecture adjustments happen early.
Architecture is the fundamental aspect of any software. Poor decisions may expose numerous flaws in performance, maintainability, testability, and others. Luckily, it is also one of the first phases of any task, so reviewing it early in the process makes sure you are heading in the correct direction and can still relatively easily make alterations.
Having to finish your day with a pull request means that you need to plan its scope and ways to achieve that. This way, developers naturally start to plan better. It makes them more aware of the overall progress and saves a lot of stress.
The team knows more about the codebase.
This one is an easy gain. The ability to properly review the code of other team members makes you aware of what is going on in other parts of the project. Next time you gotta fix a bug you go: ”Ah! I’ve seen this before!”.
Side effect — a motivational tool
While all the benefits mentioned above can significantly improve your workflow and help your team develop their skills, there is yet another massive advantage to gain. Last but not least, the daily code reviews rule can be very well considered a motivational tool.
As all of us have various triggers that keep us motivated, a considerable obstacle to an effective day is procrastination. And just some of the known methods to fight it are: starting your day with a small task and setting short-term goals. DCR introduces just that. Doing a code review first thing in the morning lets you complete your first task of the day. Likewise, finishing your day with a planned pull request can give you a feeling of accomplishment.
We integrated Daily Code Reviews into our workflow and never looked back. We have changed what the code review process means to us and feel that we make the most out of it. Now, the useless and painfully tedious task makes a lot more sense and brings value. We have improved upon numerous aspects of development from code quality and skill growth to knowledge sharing and motivation. After over a year of making pull requests and reviewing them daily, it is an integral part of our workflow and is here to stay.