One such tool is GitHub’s Pull Request Template. In addition to being an extremely useful guide for new contributors in open source projects, having a template codifies processes and encourages adherence to it even for internal projects. It also prompts developers to think about their work in context, and to empathize with reviewers.
Our workflow starts with developers self-assigning issues and working on them. They make a new branch for their work (usually with their initials and a brief description, like
tt/improve-sidebar-scrolling) and add their commits to it. Once they have enough work to be reviewed by a fellow developer, they open a pull request and assign it to a reviewer. The reviewer looks at the code, pulls it down, merges it on
develop locally, and runs the app to test the changes. Other non-assigned developers are encouraged to do code reviews as well, and offer feedback and suggestions. Once all feedback has been addressed, the reviewer assigns it back to the developer, who then merges it.
Most collaboration happens during pull request review. Pull requests trigger formal interaction with other members of the team, and are also forums for discussions. These discussions are much smoother if some basic information is readily available: an overview or justification of changes, demos or notes, links to issues being addressed, and testing instructions for the reviewer. We’ve found that a template that includes space for these elements encourages developers to think more holistically about the changes by putting them in context, as well as empathize better with reviewers by anticipating their needs and easing code review.
The current iteration of the template looks like this:
Brief description of what this PR does, and why it is needed.
curl examples, etc.
Optional. Ancillary topics, caveats, alternative strategies that didn't work out, anything else.
## Testing Instructions
* How to test this PR
* Prefer bulleted description
* Start after checking out this branch
* Include any setup required, such as bundling scripts, restarting services, etc.
* Include test case, and expected output
We’ll talk about each section in turn.
The Overview is the first of two main sections of the pull request. It is written in paragraphs, and should justify the pull request itself. A brief description of what issues and how they are addressed is expected. This should also put the pull request in context of a larger effort, referring to previous or upcoming related tasks. Just like good commit messages, it should capture the why which might not be apparent from the code itself.
Immediately following the description is a Connects line. There should be one, each in its own line, for each issue this addresses. This is used by Waffle to link pull requests to issues in their kanban view.
The Demo is an optional sub-section of Overview, but it is strongly encouraged to be included. If the pull request produces any sort of functional behavior, it should be included here. For work that makes changes to the user interface, screenshots should be attached here. For work that changes APIs,
http examples should be included. For non-functional changes, such as performance improvements, relevant benchmarks should be added.
In addition to showing that the code worked on at least the developer’s own machine, this section is also a handy tool for non-developer reviewers like designers and project managers who can get a quick sense of the work without having to pull it down and spin it up. It is also useful during sprint reviews, because each pull request has information on how to demo it.
The Notes is another optional sub-section, which is less frequently used. It is a place to list any assumptions made, which may not be immediately obvious from the code. It is also a place to mention alternative strategies that may or may not have been tried, and to briefly describe any pros or cons. It may also be a place to ask questions to the reviewer.
Its use is almost a matter of taste, as some developers simply add all details in the main Overview section. However, when present, reviewers are encouraged to pay special attention to it. It can be a springboard into deep technical discussions that weigh merits of different strategies, or reveal faults in the design that warrant rethinking and refactoring, or expose and validate assumptions that underlie actual code.
The second main section of the pull request, and arguably the most important one. It contains instructions, presented in a bulleted list, of steps to take to test the work done. This should include any special steps the reviewer has to take, such as running migrations or setting up environment variables and reprovisioning. There should be a number of statements that begin with “Ensure …” that explicitly state the expected values to be observed. For example:
* Check out this branch and run
server.sh* Open the app, and go to the second screen. * Click the green button. Ensure you see a pop-up that says “Hello!” * Click the red button. Ensure you see a pop-up that says “Goodbye!” * Ensure the yellow button still works as before. * Try out any other tests you can think of.
The instructions should be clear enough for people to follow, but can be vague enough to imply previous knowledge, e.g. “works as before” or “any other tests you can think of”.
Model My Watershed and Geosite Framework are two of our open source projects that use this template. WikiWatershed/model-my-watershed#1699 and WikiWatershed/model-my-watershed#1463 are two examples of the template filled out in real pull requests.
The template has been adopted by other teams at Azavea as well. An interesting variation, developed for the Raster Foundry project, has checklists. These encourage developers to pay attention to side-effects of changing code, such as updating the style guide or Swagger spec, and ensure that documentation is updated in sync with code. This variation is also used by the Urban Apps team on some of their projects.
Pull request templates help guide developers make better software, and a better software development experience. They are obviously extremely useful for open source projects that get many contributions from outsiders, but they can also be very useful for internal projects where all contributors are insiders. They codify and encourage good behavior, thoughtful code, and empathetic interactions with teammates. They normalize and reinforce a workflow regardless of size, scope, or underlying technology used in a project. And they provide consistency and familiarity that makes switching between multiple projects per day a little easier.
Have you used pull request templates in any projects? What was your experience like? Tell us on Twitter at @azavea!