Trunk Based Development
The current way of doing things and its problems
Probably the most common way of using source control in microservices is a variation of the feature-branch model. It usually goes like this:
- There is a
mainbranch which has the most recent stable version of the code, either automatically or periodically released to production, - Sometimes there are also
developandstagingbranches, which are deployed to safe non-production environments and allow for testing, integration, and debugging, - If you want to implement a new feature or fix a bug, you create a feature branch based on either
mainordevelop. You work on it for several days, then create a Pull Request (PR) that requires a review and an approval. Finally, your code is merged to the branch and released either straight away or at some point in the future.

You might have already noticed some disadvantages of this approach. For example, if your feature branch lives too long, it will eventually diverge a lot from the base, requiring you to merge it in and fix the conflicts. Each merge involves the risk of someone making mistakes and introducing bugs.
Often the changes introduced in other branches will break your code, sometimes multiple times per feature. Tests are not guaranteed to catch everything, especially because they also change from merge to merge.
If the feature is fairly complicated, the PR will usually be pretty large and require a sustained cognitive effort from the reviewer to understand. A lot of people will just give up and only do a superficial review – and it’s hard to blame them!
Yet another issue is that in order to test your code in a non-local environment you first complete the whole thing and then wait for approval. In the end, after testing the code on the dev environment, you will most likely need to go through the whole process again to verify the bug fixes.
Trunk Based Development – overview
The core idea of Trunk Based Development (TBD) is this: Since we already have CI/CD, a safety network of tests, and the ability to release the code easily, what’s stopping us from doing it more often that once every feature? Maybe we can even deploy our software with each commit.
This way you won’t have as many conflicts, because everyone pulls the base pretty often, and you will get feedback quickly.
Let’s assume we only have one branch: the trunk. If you want to add a feature, you pull the current version and start working. After you’ve done some work you want to release, just build it, run the tests, and if it works – commit it, and finally push it to the trunk. Done!
The technique may sound like it’s more suited for small projects and teams, but in fact large companies have used it with great success. For example, Google uses a variant of TBD in their monorepo.
Always be release-ready!
The important rule is that you must always be release ready. That means that after every commit your trunk can be built and released as it is. If you see that the latest commit didn’t pass the tests, you can just revert that commit and release what you had before.
This might seem overly restrictive – after all, if your feature is unfinished, you still need to change a lot of things and don’t want the users to start using it as it is. However, you can use feature flags and other techniques to hide the unfinished functionality.
The reason for this is not only that business needs might surprise you. The other consideration is that contributors will be pulling the code from trunk often, so you don’t want to break their builds.
Code reviews
If you push straight to the trunk, when do we do code reviews? There are several ways of handling it.
- You could switch to pair programming, and then consider a pair-developed code as already reviewed. Pair programming however won’t go well with a lot of programmers, so this is perhaps not the best solution, unless your team is on board.
- Another way is to still create branches, but not link them one-to-one with features. Those would be just short-lived code review branches, and you can have many of them per feature. If you have a commit or two that you want reviewed and merged, then you just create a PR and assign a colleague. This way you have smaller PRs which are easier to review.

- You could do a periodic code review in bulk (e.g. before releasing it to production), and address the issues later is separate commits. This might be difficult, though, because of how large the effort would be each time.
Release branches
Sometimes, regardless of your best efforts, the trunk is not ready for production deployment, but business needs force you to release it quickly. You could fix all the bugs, but this takes time and you risk other people introducing other breaking changes in the meantime. In that case, you could create a short-lived release branch and fix the problems there. Then, after your software is released, the development can continue as usual on the trunk.

Summary
Trunk Based Development is an alternative source control strategy, which can be used by teams to speed up code integration and feedback and reduce the number of conflicts and manual merges.
It works best with small, highly collaborative teams and frequent code reviews, so it’s a great fit for microservices, but can be used for larger projects as well. To be fully successful, it requires a safety net of tests and a good CI/CD pipeline.
References
Meet the geek-tastic people, and allow us to amaze you with what it's like to work with j‑labs!
Contact us


