Trunk-based development is one of several branching strategies frequently used by teams practicing continuous integration and continuous delivery/deployment (CI/CD). With trunk-based development, you commit changes directly to the master branch (aka trunk), rather than developing features or bug fixes in separate branches and merging them to master at some later stage.
Committing changes to the master branch triggers the CI/CD pipeline. If the pipeline flags up any failures, it is everyone’s responsibility to jump in to try and fix it as soon as possible. The aim is to keep the master branch in a deployable state, with changes being released frequently.
If you’re already familiar with the principles of CI/CD, you probably recognized from the foregoing description that trunk-based development is a good fit for continuous integration and deployment. As long as everyone on your team commits their changes regularly, you get the benefits of visibility of everyone’s changes and regular, rapid feedback on what is being built.
The primacy of keeping the master branch healthy and in a releasable state encourages everyone to add tests for their changes as they go. Monitoring test coverage metrics will help you keep an eye on this, while ensuring everyone builds locally (perhaps also running a basic set of automated tests) before committing will reduce the number of issues found on master.
Some advocates of trunk-based development argue that it is the only way to achieve continuous integration, and that use of development or feature branches only undermines the benefits of CI/CD. However, trunk-based development also has its downsides.
While it is a great fit for continuous deployment, where code changes that pass all stages of the pipeline are released automatically, the model works best for SaaS products, where there is a high tolerance for – and even an expectation of – continuous updates.
If you’re building an installed product or mobile app, you may want to batch up changes into periodic releases rather than creating a new version for every update that comes through the pipeline. In that case, using branches makes it easier to manage what is included in each release and provides ongoing support for multiple product versions.
A potential challenge of trunk-based development involves how you handle the development of large or complex features. Committing changes to master regularly while deploying it directly to production requires a way to manage functionality that you don’t yet want to make visible to users.
For trunk-based development, feature flags provide a way to control the visibility of features, but managing these can be complex. An alternative is to opt for a branching strategy that includes feature branches, so that you can keep functionality separate until you’re ready to release it.
For teams that are new to CI/CD, committing changes directly to master while keeping it deployable can be challenging before you’ve had time to develop a robust test suite. If trunk-based development would otherwise be a good fit, it’s worth making it a goal that you can work towards as your CI/CD practice matures.
Trunk-based development is a good fit for continuous integration and deployment that works best if you have a robust automated testing suite and don’t need to support multiple versions of your software or group updates into releases. However, it’s certainly not the only way and other branching strategies may offer a better fit, depending on your circumstances.