Integrating Code in Agile Software Development: Start with the Goal in Mind
I was once at a conference session where the speaker advocated against branching and pull requests and for integration to the master on every commit. One of my colleagues argued that pull requests and code reviews were an essential part of the development process. The speaker countered that testing and pair programming were sufficient. My colleague argued that a pull request process mitigated risk, and on it went.
Given that both parties were knowledgeable and thoughtful about agile software development, and as someone who appreciates the value of branching as well as the perils of delayed integration, I wondered if they were arguing about the wrong thing by focusing on practices without considering whether the practices were helping them achieve the right goal.
Agile software development works because of continuous feedback at various levels, but the most important form of feedback is working software. One way to achieve rapid feedback on the state of the software is to integrate and deploy frequently. Frequent integration not only helps customers see the latest application state, but also helps developers make changes rapidly.
Small, incremental changes are easier to test and integrate because the less that has changed, the less there is to test. Frequently integrating small changes to the master directly, without a branch or pull request, could be faster, but it’s not guaranteed.
A pull request process offers some advantages. Pull requests can allow for a wider review group (both more people and more widely distributed people) than pair programming. Tooling associated with automated builds can verify that the code satisfies the prerequisites of merging safely, such as building, passing tests, and meeting style and other guidelines, so that people can then focus on more conceptual questions. While there are other ways to achieve the goals a review process satisfies, a pull request process need not excessively delay integration.
Agile software development values frequent integration. “Frequent” can vary by team, but it’s rarely truly continuous. A change requires work on the developer’s part, so delays between the time when code is changed and when it is integrated are almost impossible to avoid. In the case of a team that values frequent integration, the question is how frequent. In many cases, the practical answer is that code be integrated to the master once or twice a day.
Rather than starting the conversation about whether to branch or to use a pull request process, it’s best to begin with agreeing on the ultimate goal, which is to integrate code at whatever frequency is best for the team.
As long as pull requests are consistently reviewed and merged daily, we can meet our goal. If integrating to the master directly reliably results in working software, that works, too. The key is to have the team adopt a process that they agree will meet their values and inspect whether the process is working—and adapt if it is not.
At the end of the conference session, it became clear that my colleague and the speaker were both advocating for merging to the master at least once per day. If they had started with the goal in mind, rather than the process, they would have realized that they were more in agreement than they thought, and that either means could achieve the same end.