In software development, the name of the game is to develop reliable systems in a fast-paced manner. As development shops have evolved to increase the speed of delivery, many organizations have embraced the Agile development practices of continuous integration and continuous deployment (CI/CD).
But the very nature of fast-paced development introduces challenges — particularly around the quality and the reliability of the software being developed. The development process that defines how developers interact with source control and integrate new features and other modifications on a day-to-day basis is often omitted from the discussion of software quality.
Today, there are several popular methods for defining this process. In this article, let’s focus on one method: trunk-based development. We’ll look at:
- What trunk-based development is
- How it’s leveraged for the management of a CI/CD pipeline
- The benefits of trunk-based development in terms of developing reliable software in a fast-paced development environment
What is trunk-based development?
Trunk-based development (TBD) refers to a process for managing a project within source control where all developers working on the project commit their code changes directly to the trunk (primary/master) branch.
With trunk-based development, developers avoiding utilizing long-running feature branches – these can cause devs to fall drastically out of sync with other team members collaborating on the same project. Instead, you can use short-running branches where necessary, keeping them small to prevent the developer from straying too far from the state of the trunk’s source code.
The trunk-based method is made possible by enforcing a smaller scope for application changes that allows for the gradual integration of features within the codebase (sometimes done with the help of feature flags). Leveraging this method can lead to an array of benefits that will make the life of developers and IT teams significantly better.
Principles of trunk-based development
When working in long-running feature branches with fewer commits to the shared branch, the opportunity to cross-validate code from other developers doesn’t arise often. And, when these branches are finally integrated, the changesets are bigger, more complex and have been concealed from all other team members for a long period of time.
In contrast, here’s how this validation process works when doing trunk-based development.
- Trunk-based development dictates that the scope of the changes made to the codebase for a particular task are limited, to prevent the creation of long-running branches.
- With these limitations being the case, all developers commit their code to trunk on a regular basis as tasks are completed (with some even committing multiple times per day), leading to efficient release management and more frequent deployments.
- Since no developer is waiting extended periods of time to integrate their changes with the trunk, the complexity of a potential merge is kept to a minimum. Conflicts are, therefore, fewer in number and much less tricky to resolve than when trying to integrate a long-running branch with master on the heels of other recent merges containing significant changes.
- With lowered merge complexity comes a lower likelihood of mistakes being made within a merge (i.e., leaving in code that shouldn’t be there, removing code that should remain, etc.).
Benefits of trunk-based development
With these principles in mind, let’s look at the benefits of this approach.
Stay in-sync for less frustrating merge scenarios
A key principle of trunk-based development states that developers are prevented from falling out-of-sync by eliminating the practice of creating and working in long-running feature branches. This allows all developers to remain generally in-sync with those working around them – resulting in:
- More reliable services
- Better incident management processes
This provides a specific noticeable benefit: merging in code becomes simpler and faster. Most importantly? It no longer holds the anxiety-inducing prospects it once did.
Reduce chance of build & integration issues
Another significant benefit of trunk-based development is a reduction in build issues due to a higher-level of responsibility being taken by all team members to keep it functioning properly. With all developers committing continuously to the same branch, maintaining a functioning build is of great importance.
The notion that the build must be kept in working order at all times helps developers buy into on-call responsibilities and turns resilience into the credo of every developer on the project. In addition, with developers merging their changes into trunk with such great frequency, they learn to code with the build in mind.
Furthermore, with trunk-based development, developers have an increased ability to validate their code changes against those of their colleagues.
Get more actionable insights
With greater visibility comes greater insight. And insight is exactly what’s provided by the continual process of merging small sets of code changes into an application and making minor continuous improvements. Prior to checking in, developers merge all recently committed changes from other team members into their local copy of the source code.
Developers can then proceed to build and test on their local machine. This provides the developer with all they need to ensure local changes work in conjunction with all recent commits. In this manner, trunk-based development inherently ensures a base-level of quality within the application, simply through increased visibility into the work of other team members.
Pairs perfectly with CI/CD
Trunk-based development is, in many ways, tailor-made for the concepts of CI/CD. In TBD, all developers merge changes frequently into the master branch. For each team member, this could mean:
- As little as one commit every 1-2 days
- Several commits per day
With each commit, a build can be triggered with full-unit and integration testing, followed by deployments to testing environments.
A continuous stream of commits containing small changesets causes the fully up-to-date and integrated trunk branch to build and validate frequently, leading to an application that becomes increasingly stable as it evolves. And, as an added benefit of the oft-run CI process, the application is always in a state that’s ready for deployment with the latest and greatest features present.
So how does delivery work in trunk-based development? It’s actually quite simple. When it’s time for a release, a new branch is created off of the trunk. This release branch is not to be tampered with by developers outside of extreme circumstances.
(Don’t forget anything with this production review checklist.)
If a production bug exists in the release and a patch is necessary, the fix should be made in trunk and the code fixing the bug should be patched into the release branch to be deployed. Release branches are later deleted when it’s certain they will no longer be needed, keeping the repository clean and maintaining a process where source code moves in one direction – from trunk forward.
Support rapid development with TBD
When employed properly, the principles governing trunk-based development allow for the rapid development of high-quality, reliable applications. In a world that craves fast-paced application development, this can be very valuable.
In order to implement this process properly, the scope of application changes must be kept small and code must be integrated as often as possible with trunk. With each merge from each developer triggering a full application build — complete with integration testing — issues within the codebase are easy to spot and likely to be fixed in a swift manner by those who introduced them.
What is Splunk?
This posting does not necessarily represent Splunk's position, strategies or opinion.