Startup development teams need to optimize for speed. Code needs to ship quickly to validate ideas, and it needs to turn on a dime as feedback comes in. Perfect code that solves the wrong problem or ships too late is of no use to the company.
But speed needs to be balanced with quality, and one of the most effective tools for ensuring quality (as well as sharing knowledge and coordinating) is code review.
Sadly, most existing solutions for code review involve an undue sacrifice of velocity. But after trying various workflows over the past few years, I’ve got something I feel pretty good about. By layering a few scripts on top of GitHub and Reviewable, it’s possible to balance code review and speed.
Pull requests are heavy
Pull requests are a great idea for large open source projects, where whole concepts are either accepted or rejected by committers, and velocity is less important than quality. Unfortunately, the dominance of GitHub has also made them the default workflow for commercial software development, even thought it it slows things down. Pull requests are just too heavy.
Too many steps to create branches, keep them in sync, and assign them for review
Weight discourages frequent commits and encourages long-lived branches
Avoids error-prone large merges, noisy merge commits, and overwhelming code reviews
Stops developers from going too far down any bad paths
Encourages tighter collaboration within and between teams
Is more conducive to refactoring and shared ownership
Generally allows teams to move more quickly
Google relies on custom tooling to make this work, though, so what’s a person to do?
Close, but no cigar
At Foursquare, we used Facebook’s code review tool, Phabricator. Phab ostensibly provides all the benefits of a Google-style agile workflow — review code written against master, and just commit to master when you’re ready. But in practice, it wasn’t satisfying.
Feels a little cluttered if you’re using GitHub or other tools for everything else
Tedious to configure and performance degrades
Hard to fit arc.sh or commit hooks into your workflow
Hard to make sure code actually gets reviewed
Lots of existing SaaS CI and code quality tools only plug in to pull requests
A middle ground
Given all of this, I was determined to find a middle ground for our new engineering team at Scroll. Our solution uses a shell script, a tiny go server on Heroku, and Reviewable to do a few things.
Only branch when it’s time to review code, not before. (This helps ensure, among other things, you’re very close to master by doing a pull with rebase right before.)
Automate generating and assigning pull requests so it’s a single command line. (Assigning a review is key to making it sure it happens and happens quickly, which along with the ease of the single command creates a positive feedback loop for smaller code reviews and increases overall team velocity.)
Make sure coders and reviewers are notified immediately when it’s their turn. (Again, keeping the review velocity high to keep the flywheel turning.)
Try it out
Steps 1 and 2 are covered by the shell script. It assumes you generate a GitHub personal token with repo permissions and place it in ~/.ghtoken. With this setup, a developer writes code in master, and when they’re ready for code review, they run ./review.sh [reviewer], and the script syncs with master, creates a branch, commits any uncommitted code, pushes it, generates a pull request, and assigns it.
Not strictly required, but I’m a big fan of Reviewable for code reviews, which fills all the holes in GitHub’s code review workflow. (Mihai put this on my radar after noticing Cockroach uses it.)
Sadly, Reviewable lacks Slack integration, and GitHub’s notifications are also inadequate. So Step 3 is covered by the simple go program. It’s configured using two environment variables: SLACKURL is the webhook URL you create using the button on https://api.slack.com/custom-integrations, and USERMAP is a ;-delimited list of githublogin,slacklogin pairs, e.g. johnny24,johnny;bob,slackbob. Once you create the Heroku instance, add its URL as a webhook in Github for issue comment and pull request events. When a pull request is created or reviewed, this script is notified and sends a direct message to the correct person in Slack.
So far, so good
We’re just starting out with this code workflow, but so far it’s great. We can review code, benefit from all the tooling built around pull requests, and still move with almost the same agility as committing directly to master. It’s not perfect, and it’d be interesting to hear what other folks are doing or how this solution works for you. Reply with your thoughts below, on HN, or to @krave on Twitter.