A few months ago, I started working on a new project, and the team decided to insert some innovative technology and try a new branching model called Trunk Based Development (TBD).
We usually have a “Story” backlog to work on. The work is divided into a two-week “Sprint” and, with a meeting at the beginning of each sprint, we decide which Story to work on. At that point, the developers are free to work on any Story in the “To Do” state, keeping an eye on priorities decided during the sprint meeting.
The branching model we usually use is a variant of the well-known “GitHub Flow”:
- When you start the development on a Story, a branch is created from master.
- You work on that branch without thinking about anything else. Development can last hours, days, weeks. When the work is finished, the code is pushed to the server, and the build tool (Jenkins) tries to build and run the tests.
- If everything works, a Pull Request (PR) is opened to the branch master, which all team members can review. Those who want can make comments by entering a comment on the PR and, if necessary, changes are made and then pushed, waiting for new approvals from the team.
- Once the PR has been approved, the merge on the branch master is made and the Continuous Integration (CI) process starts a build creating the “package” to deploy on different application environments.
The problem with this workflow is the part of PR code reviews opened. The mechanism by which the code is reviewed (consisting of comments, responses, implementations, and feedbacks) can sometimes last weeks: actually, those who review the code usually also manage other activities, since there are not review-dedicated persons, and this can significantly slow down the development cycle.
To overcome this problem, we decided to use the TBD, which consists of pushing the code directly onto the branch master, with no need to create other branches. I know it may sound weird, but keep read on.
How can we make TBD?
Obviously it is not enough pushing on master: in order to have a real advantage from this model, you must respect some rules.
Each commit must leave the application in a “working” state, and no tests must fail, so you have to organize the development of your feature, especially if it is large, to achieve this result.
At least two pairs of eyes on each line of code: this way, the code is subjected to the control of multiple people.
It can happen, during the development, that the branch master contains features that have not yet been tested, and that we still do not want to bring to the attention of the business. We can disable them using feature flags technique (I recommend this interesting article by Martin Fowler: Feature Toggles (aka Feature Flags) (martinfowler.com).
No longer having the pull request mechanism, the code review is postponed to a weekly meeting in which to discuss the various implementations made. In this meeting, a presenter explains what has been developed and the other participants make any comments. Changes can happen directly during the meeting.
How our development has improved
Starting with this approach was difficult. The main problem to deal with is to find the right size of commits to push. Initially, some team members were not confident in pushing small, robust commits, but rather preferred a single push as the feature was completed, causing several problems in code merging.
Despite this, after the first phase of adjustment, the team has found many benefits from this model, and I try to list some of them.
The code belongs to the team
When a feature’s code is written by a single person, who follows its entire loop up to merge on master, there is a tendency to believe that code is a “property” of the developer who wrote it. Using the TBD, the code belongs to the team because, with each commit you see your application growing, perhaps refactoring on a part of code previously pushed by your colleague, making the development more dynamic and team.
With the PR mechanism, feedbacks only come as the work has been done. The code review stage is complicated to manage: our team doesn’t have persons dedicated, then we must find out the time to make it. Once done, if anyone finds something he/she’s not sure about, he/she leaves a comment, and the other person in charge has to find the time to view it and answer if necessary. This process requires a strong interaction among different parts, and it may also be motivating, but it is usually a mere approval. On the contrary, when there is a continuous commit flow, code reviews are always in progress, so choosing a different path can be easier to implement.
Better feedback quality
With PR, comments come in the form of comments, written in a text box, with all the difficulties of the case. The reviewer may not be able to express his point of view correctly, or the developer may not grasp the exact reason for the comment, considering it almost a personal attack.
Having the opportunity to discuss the code in real time, perhaps while doing Pair Programming, certainly avoids misunderstandings and makes development smoother.
Team development methodology
Pair programming and TBD lead the team to create a development methodology shared by everyone, making subsequent code reviews simple and fast.
Propensity to refactor
When a PR gets the required approvals and is brought to the branch master, it tends to be considered as finished, although the pushed code would need some refactoring. You try to avoid it mainly to prevent problems with merge, which may be necessary. When development is continuous, refactoring small pieces of code becomes easier and there is no need to take the risk of solving complex merge conflicts.
Visibility at everyone’s work
When developments take place in a separate branch they are invisible until the branch is pushed. If, on the other hand, everyone pushes on the branch master there is the possibility, in real time, to see which features the team works on at that time.
Does TBD fit all teams?
I want to clarify one point: TBD development in itself offers no objective advantage and if you think about it, it is nothing special. What instead gives objective advantages are the practices that you need to put in place to be able to perform trunk-based development.
For a team to be able to work directly on masters, everyone needs to be able to work without breaking the code, everyone knows how to write robust tests, and everyone knows how to work together effectively.
How to get started?
If you are currently developing in feature branches and want to start using TBD, I would recommend two things to you:
- Fortify the way you write tests. Try to work to get to a build that you think has no problems, even if you can never be sure. Try using the TDD (Test Driven Development) technique, so you’ll realize you’re putting in an amount of testing that almost manages to cover everything your application can do.
- Do Pair Programming. Deleting the Pull Request and Code Review process is critical that the code is developed under the control of at least two people.
- Code analysis: It is possible to integrate static code analysis mechanisms into your CI (we use Sonarqube). We can thus make the style rules enforcing, simplifying even more part of the review process.
I hope I intrugued you about a new way of developing.
See you at the next article
Francesco de Vicariis