This is part three in my series on Modern Software Development Practices. In the series, I plan to cover multiple ways in which software engineers can improve their software by improving their processes and practices, all of which I have learned and lived through my time as a Software Consultant at ThoughtWorks and experiences at my current job at a large retail company in Germany.
As someone who likes to advocate for things which I believe to be very beneficial to the efficiency of a Software Development Team, I have spent a lot of time dealing with push-back on some of the practices I believe in.
One of my absolute favorite topics is Trunk Based Development (TBD). Coincidentally, that topic also receives the most backlash from other Software Developers.
I love this topic because I do not like stereotypes, and Trunk Based Development directly combats a lot of stereotypes that Software Developers fall victim to.
When people outside of our industry hear the phrase “Software Developer”, they think of the mythos of a Software Engineer. Almost like a mythical creature, this is someone who puts on headphones, works with 3 or 4 monitors, and green characters on black screens. Someone who receives a task and then goes away into their cave-like work environment until they have completed their task a short time later.
A perfect example of this, is the creator of the 2048 game. Rumor has it a 19 year old built the game in one weekend, and 2.5 weeks after releasing the game, the game had 100 million plays
That is the Software Developer stereotype perfectly personified. While sometimes cool, I believe that this has a negative impact when developing software as a team.
Trunk Based Development is a form of development which literally can not be done while the stereotype developer exists in the team.
Trunk Based Development requires teamwork, empathy, and openness. All of which are best achieved as a team, and not as an individual.
What is Trunk Based Development?
Trunk Based Development, also known as TBD, is a software development process which is defined by trunkbaseddevelopment.com (a great source for all things TBD) as:
“A source-control branching model, where developers collaborate on code in a single branch called ‘trunk’ *, resist any pressure to create other long-lived development branches by employing documented techniques. They therefore avoid merge hell, do not break the build, and live happily ever after.”
The idea is, instead of creating a feature branch on which a developer develops code, and then merges into the master branch, the feature is developed in small chunks, each of which are directly pushed onto master when finished.
In other words… the team develops without using any branches.
Now… I know that most developers who have been in the industry for a while are instantly turned off to the idea of TBD when they see “pushed onto master”… but hear me out and I’ll try to address the concerns I hear the most throughout this article.
Why’s it important?
Once again I go back to the Four Key Metrics as defined in Accelerate and their importance. A direct quote from the book:
“our research highlights practices that are essential to successful technology transformations. These include the use of version control, deployment automation, continuous integration, trunk based development, and a loosely coupled architecture.”
Practices which are not just important.. but essential. Meaning absolutely necessary. I wrote about Continuous Integration a few posts ago and Trunk Based Development is in that list as well.
Apart from the fact that small code changes in a Trunk Based Development format results in much less merge conflicts (which means happier developers), Trunk Based Development helps teams improve in a number of areas:
Deployment Frequency and Mean Time to Recovery
TBD paired with a CI/CD pipeline results in every “green” commit (i.e. the complete code functionality has been checked via tests) being deployed to production. Pushing every change to the master branch means lots of integration and potentially deployment. I have been in teams where we deployed 30–40 times in one day to production. An increased deployment frequency is the second of the four key metrics.
I can remember a situation in that very same team where we had deployed something to a front-end application which was something along the lines of “display the list of items with their respective attributes” and we had forgotten to check for null or undefined values. This caused the front end to have an error.
Of course this is something that could happen to any team regardless of what processes they use… but what was amazing was that we noticed it right away, and were able to write a test and fix for the issue which was committed and deployed to production in less than 5 minutes. A low Mean Time to Recovery is the third of the four key metrics.
This ability to deploy changes quickly via Trunk Based Development and CI/CD also allows the team to “roll-forward” when problems are discovered, rather than “rolling-back”.
Code Quality and Knowledge Sharing
The biggest fear teams usually have when considering TBD is that the quality of code in the code base will suffer when doing Trunk Based Development and the potential for errors will go up. I, however, have exactly the opposite opinion and believe that TBD results in much more resilient and higher quality code.
Most teams who use feature branches, use the pull request method, where other developers in the team will look at, and comment on, code that a developer has worked on over X amount of time.
With TBD, since there are no feature branches, that also means no pull requests. Insert worried Senior Dev here. This does not have to be an issue. Most teams just want a “4 Eye Principle” which says that at least 2 developers should have looked at and approved all code that is merged into the master branch.
My team does the “4 Eye Principle” as well, but we do it via Pair Programming (article coming soon). Since there are no pull requests in TBD, Pair Programming becomes extremely necessary.
Two developers working together to solve the same problem is quite often better than one developer working alone. All developers have varying levels of experience and familiarity with the tech stack and/or system the team is developing. Pairing with each other provides the opportunity to learn from teammates at an accelerated rate.
Imagine how quickly a junior engineer or new hire levels up when pairing with a senior engineer in the team. Team coding guidelines are instantly learned and met, design decisions are made before the work is done rather than as feedback in a pull request, and code is written together resulting in both developers having knowledge of how it works (i.e. less knowledge silos).
Pair Programming is obviously a form of teamwork as well, but TBD improves teamwork in the team due to the way it requires empathy from all members.
It can be challenging as a senior developer who has worked on a system for many years to feel comfortable with new or less experienced team members committing to the code base without the senior seeing it. But the empathy required to be ok with this is generally a very positive quality to have as a teammate. Believing that one’s teammates are capable at doing their jobs and not needing to be the master branch gate-keeper is very important to the confidence and trust within the team.
Senior engineers are smart and have good experience most of the time, but the people in their teams are smart too. If the senior would like to see the code written by a junior, they can pair together, and sooner than they know it, the junior will be writing code that the senior would be proud of.
Nobody wants to push unfinished features, such as a button with no functionality, to customers on production. To get around this, teams can implement feature toggles behind which unfinished features are hidden. When a feature is not done, the feature toggle is turned off, and when the final piece is done and ready to be released, the feature flag can be toggled on (or removed completely). With feature toggles, teams can even do A/B testing or Canary Releases.
Tests and monitoring
Trunk Based Development requires that a team has a strong test suite and good monitoring in order to catch errors as soon as possible. The quicker the feedback loop, the better. A broken pipeline becomes the number one priority for the team members who broke the pipeline, to prevent any others from pulling broken code.
This can be easily prevented by implementing very small changes, having a development environment which is as similar as possible to your testing and production environments, and by running pipeline tasks locally before pushing (ex. using git hooks).
I know many teams who have implemented Trunk Based Development as described in this article, and none of them have switched back to the more common Pull Request model.
Some teams even switch to Trunk Based Development for other reasons, such as they want to do more pair programming, so they switched to TBD in order to make pair programming a bit more of a requirement.
I think the important part to remember is that like all things in software, and in life, the same thing doesn’t work for everybody. It is important that teams look at what works best for them. An example would be a team I knew who had an odd number of developers, meaning they did not have the ability to pair on all tasks, and were sometimes burned out from pairing so frequently. In this situation they had feature branches which were created and merged on the very same day, which surprisingly enough, counts as TBD.
Next steps: try out Trunk Based Development, adapt it to the team’s needs, profit.