Team software development can be challenging, and while we often talk about tools and methods that teams use, the forces that affect the dynamics of development extend beyond the code/build/test/ release process. Patterns are be a useful form for navigating the related issues.
The patterns in the book Software Configuration Management Patterns captured the development team mechanics. What’s missing is that the mechanics happen in the context of other organizational elements such as planning, and this is the next step in the evolution of that pattern language. By applying the patterns you can have short lived Task Branchesthat merge reliably.
Names
This conversation is often complicated by using words differently, so let me define some terms for the purpose of this conversation.
A Pull Request is the start of a process to integrate code to the main line. It can include one or more of the following:
A signal to run automated checks for a branch
A tool to use to review code (like the Git Hub PR UI)
a Gate that requires approval.
A request for feedback
Often the usage implies all of these things but it need not.
A Branch is a parallel work stream, and branches are usually SCM artifacts, but not always.
The Principles and the Challenges
There is some consensus on two principles of team software development:
Working off of a single Main Line can speed development.
Some sort of review before code gets integrated into the main line is valuable.
Given this teams often struggle with how to integrate parallel streams of work, while maintaining working code, delivering features rapidly, and reducing knowledge silos, specifically:
How to organize the individual work streams, and
Which mechanisms to use to get feedback on code.
Branching Workflows
A common approach for managing parallel development streams is to
Work on a branch:
Implement code
Run automated tests and other checks
Submit a Pull Request when the work is “done”.
Get and apply feedback
Merge when reviewed.
At times the Branch/Pull Request/Merge process can be frustrating:
Feedback is slow or poor quality
Merging is hard due to conflicts
Code takes too long to get merge
A first reaction to addressing this problem is by using a workflow like this
Pulling code from Main
Implementing til work is done
Running automated checks and tests in a developer workspace
Asking for feedback from a peer
Doing reviews in a developer workspace.
Merge to the Main Line
This skips the branching step, but conceptually it’s not that different from the PR flow: A workspace is also a parallel work stream, much like a branch, but without the transparency and automaton support branching enables.
A good, agile, development process enables you to minimize time to a successful integration, which means:
Minimizing the amount of unintegrated work.
Minimizing the idle time (for example, time spent waiting for a review)
Maximizing the quality of the feedback
There are a few ways to get there, and seemingly easy fixes may hide root causes.
Root Causes
Code in a workspace is conceptually the same as a branch, with all the challenges and none of the advantages; if your process works without branches there is no change. Many teams don’t have a dynamic that makes direct to main with no branch merging work reliably.
A Branch and push to a repository enables useful automation. Even if you want to move away from Task Branches, for whatever reason, the context that speeds up your PR Review with Branches process is still necessary for effective branch-less workflows.
The problems teams have with integration feedback include:
For the person submitting the pull request:
Feedback is Slow, leading to a loss of momentum, and sometimes a more complicated merge later.
Feedback is sometimes disjointed or at the wrong level: the reviewers don’t have the context to give the right kind of feedback, raise issues that were already considered, or are trivial (like formatting).
For the reviewer:
Pull Requests seem like a distraction from the real work, and are time consuming.
If they lack context, giving feedback on things like formatting and style feel like low ROI for a human reviewer.
The core problem is that it can be hard to get the right feedback in a timely manner.
What Branches can Add
The pre integration review of a Task Branch with a Pull Request in a CI environment enables:
Broadening the community of who can offer feedback (with the caveat that people with context are more valuable).
Using automation to check for simple issues like style, syntax, and vulnerability scanning.
Sanity checks in a known environment about whether the change will break the main line.
Asynchronous feedback when that makes sense (such as for remote teams), while not excluding the possibility of synchronous feedback.
The challenge is how to get both:
The benefits of tools like (short lived) task branches, and Shared Code Review Environments.
Rapid, contextual feedback.
While you see the problems in the PR process, the root causes are often elsewhere, and these same dynamics can also affect the “direct to main” process. These things include:.
Planning: do people have time to work together? Is the work planned to make short lived, rapidly integrated tasks possible?
Culture: does the organization make it safe to identify issues and explore options?
Architecture: does the code make it harder or easier to work in small changes increments.
An updated SCM pattern language gives a way to look at the the entire ecosystem so that you can build a process that uses:
Short Lived Task Branches
Checks in a Continuous Integration Environment
Review using shared tools (like your PR Tools)
Improving your workflow is not as easy as simplify removing the Pull Requests. The context/problem/solution structure of a Pattern Language captures the complexity of the relationships that affect your process in a manageable way.