We’ve been developing PullReview since six months now, putting a lot of energy in it. As the feedback from the alpha is integrated into the application, users’ questions led me to look back at the reasons we made PullReview the way it is, and the realize how much linked it is to our own development practices.
- We think coding is teamwork, that we can achieve greater results together.
- We think the best results are achieved by defining clear, separate and small development tasks, and each of us work on them sequentially.
- We think another piece of eyes can have a profound, lasting and positive impact on the code we write.
- We see in each programming task an opportunity to learn.
- We agree and push ourselves toward the Agile principle of releasing early and often.
Those are beliefs or at least opinions, but that are very important to us. We put them in practice in our internal development process.
How we work
We develop in short sprints (1 week), defining together what to do for the next sprint. We put the chosen issues in GitHub.
We schedule a few kind of issues that we try to balance in each sprint : new end-user feature, administrator/operational feature, cruft, security updates, bugs (detected by errbit, end user or by visual inspection), enhancements from "new-feature" feedback.
For major features we try to avoid overlapping in the same part of the code base. E.g. if one of us is integrating a major site redesign, the others tend to add backend feature / infrastructure changes. Again, those periods are supposed to be short. We even splitted the redesign in various issues.
We make feature branches (or bug branches) for pretty much everything (even our doc or infrastructure changes). Commits on the integration branch (whether it is develop or master or another) are few are far between, and frowned upon for all but the simplest modifications (such as a single typo).
When our issue is done, we create a Pull Request and ask for a review (of course, since several months now, we’re using our own PullReview as a first step). Except in very urgent circumstances, no one merge his own code without having another team member look at it. In other words, we’re reviewing every change before they are merged.
We incorporate review feedback on the branch, before merging. We think this is the best time to do it.
The merge is done by the reviewer, not the author. This is a symbolic choice, but one that has worked well, sharing the responsibility of the feature/bug fix/patch between the author and the reviewer. Once merged, we delete the branch immediately.
Once the new feature has been built on the staging area, we test it, and barring problem, send it into production immediately. Should there be a problem, there is only one new feature, so investigation should be quick. We keep the possibility to stage a specific branch, should it be needed to test it there before integration (example: mail notifications).
We think the review phase to be a critical piece of the development process. We use PullReview on a daily basis, just before the human review. It make a good first pass, eliminating problems that would have taken time and would have created noise on the human review.
This is no random issue: we designed PullReview to work the best with this workflow. Our design strategy was always to mimic the best we can what a human being would do, not only (or even not especially) in the rules we apply, but on the flow itself, leading to two major design choices:
1. As stated, we think that the best time for some review & refactoring is just before merging. Earlier would mix it with your feature work. Later would probably means never (once it’s merged, you’ll be busy on something else). PullReview is reviewing your work on your feature branches.
We push this way of working by focusing on the new problems, i.e. those that were not there on the branch starts, but are present on the branch tip. We want each merge to improve the codebase bit a bit (in addition to bringing features in).
We think the best way to keep a code base clean is to focus on the day to day care, instead of letting things go, then have to start a one sprint long refactoring each month or two.
2. Any review feedback should be motivated: When I coach more junior developers, I try hard to avoid the “Do it that other way. It is better - trust me”. While some trust is required, my first objective as a reviewer is not about the code (I could fix it myself, it would be much faster) but about the person I’m facing - I want him (or her) to learn something from the experience, so that the same problem does not pop up again in the next feature (I like to learn something myself too). This is the reason PullReview shows for each problem a reason why the given code is bad, and proposals in order to improve it - we think that the best way to improve the code is to improve ourselves.
We care about Code Reviews, and are quite opinionated on the subject. We’ve put most of those opinions into our software. It may not work for everyone, but we think that those sharing them will find in PullReview a natural companion to their work.