Explaining Trunk Based Development

Mahesh Mallikarjunaiah
Share this :
Share this :

Introduction

Trunk-based development is one of the most widely used branching methodologies. It helps teams collaborate and build and deliver software.
This article will examine trunk-based development, its role in the CI/CD pipeline, its pros and cons, and how it compares to other methodologies.

Background

In the good old days, when source control did not exist, developers would maintain multiple versions of code, manually tracking changes, which was very inefficient. As time progressed, developers began to use local version control systems to track changes.

Eventually, a distributed centralized version control system helped multiple developers maintain copies of the repository locally, code, make changes, commit, and collaborate efficiently to release software. With time, branching and merging became more efficient.

Branching is duplicating the code to be modified independently and in parallel. The various branches merge at some stage in their lifecycle.

Product Success and Company Success

Shipping products faster is vital today to keep up with customers’ growing requirements , survive competition, and drive customer success.

The driving factors can be divided into two parts: faster releases and enhanced customer success.

One part should focus on building successful engineering teams. Another should focus on setting up the proper software development process and leveraging the correct tools and technologies to drive engineering productivity.

Crucial processed I want to touch upon are coding, branching, and strategies. When working on a shared code and version control system, it’s essential to have a process that can help write and merge code without creating many conflicts or overhead and then smoothly release the product into a production environment.

One such process is the branching strategy, which is critical for developers to collaborate and ship code.
Branching model development involves creating multiple branches based on the needs and requirements of features, bug fixes, tech debt, enhancements, etc.

Why Branching?

Branching is primarily used to help developers. Development teams have a separate space to work on their code changes before merging into a main branch.

For example, features can be worked on separately on a branch, and bug fixes can be worked independently on a different branch, and so on, without impacting the main branch until it is ready.

Merge conflicts are difficult to deal with and are dreaded by many developers and teams because they can impact the overall product success. Having an excellent branching strategy is one reason for this.

Teams with many developers working on shared repositories know their difficulties and challenges with code merges, maintenance, branching, and releasing.

An excellent branching strategy drives developer productivity, reduces code conflicts, improves quality, and accelerates market releases.

As depicted in the above diagram, merge conflicts are complex to work with; the more time developers take, the more time to merge with the main.

Continuous Integration and Continuous Delivery

Continuous Integration is a process where code changes are often automatically built, tested, and integrated.

Robust continuous integration depends on frequent code commits, which help establish efficient continuous delivery. The integrated code should be production-ready and not break the CI/CD process. Continuous delivery should have release-ready code anytime we decide to release it.Trunk-based development is a crucial enabler for CI/CD.

Some benefits of Continuous Integration are a faster feedback loop, improved code quality, early detection of defects, drivingengineering productivity, and much more.

As depicted below, the challenges of not doing continuous integrations are many. When developers work on their code without merging with the main branch for a long time, the feedback gets delayed. When the code being committed is very large, then the conflicts will be longer and will take a lot of time to resolve.

Developers would have forgotten what they had done when they were asked to resolve the merge conflicts for a longer duration. Developers would get frustrated, impacting the overall engineering productivity and delaying releases. This will impact product success.

Trunk Based Development

One popular branching strategy that is widely used is “Trunk Based Development.”
In trunk-based development, all team members work on a single shared branch known as the trunk. There could be short-lived branches, but the emphasis is on frequent commits and maintaining shippable code at all times.

Trunk-based development also helps minimize and overcome merge conflicts, and tested code doesn’t break the build and is ready to be shipped.

A typical flow in a trunk-based development looks like the below :

  1. A team following scrum would have backlog groomed, estimated, and ready to start development
  2. There would be one trunk or main branch for the scrum team.
  3. Each developer would begin working on the user story and create feature branches from the main branches.
  4. For example, Mary can create feature branch A, and John can create feature branch B
  5. Once the work is completed, a pull request is raised
  6. CI pipeline triggers upon pull request where automated tests are run
  7. The other team members also perform code reviews
  8. Code changes are incorporated based on review comments and submitted
  9. A pull request is approved
  10. Changes are committed to the main trunk
  11. The code from the main trunk gets deployed on QA, pre-production, and eventually to the production environment
  12. Additional testing and validations are carried out on these environments 
  13. Once testing is completed, the feature is deployed to the production environment
  14. The feature can be decided when it needs to be released and available in the production environment
  15. For example, feature A could be turned on after deploying in production and released after one month
  16. Feature flags can be leveraged to turn on and turn off the features in production
  17. Featured can be available or not available for end users based on the decisions taken and settings of the feature flags

Unlike other branching strategies, trunk-based development enables the integration of small changes versus significant changes in one go.

Release branches are derived from the main branches per the plan and strategy. Branches are deleted or archived after the code goes live. Sometimes, there are no release branches, and the main trunk is used to perform production releases.

Pair programming is one of the enablers for trunk-based development. It helps review code as it is written and is very efficient.

Code reviews are also essential to drive efficiency in trunk-based development.

Ensuring the code commit doesn’t break the build is significant; hence, testing first mindset, testing early, and testing automation are critical in trunk-based development.

An emphasis on automation testing is essential to ensure it can cover all possible test scenarios to be tested and find defects. Using automated testing can help enhance the test coverage needed.

TDD is an approach that goes well with trunk-based development.

Early feedback is one of the most significant advantages of trunk-based development since it gets frequently committed, merged, and tested.

In other merge-based systems, where merges span days, this will only make merge conflicts bigger and more challenging to handle, eventually preventing merges from happening.

Trunk-based development is recommended to be used when continuous Integration and delivery are critical, decouple releases and deployments, a main branch that only runs in production, avoids merge conflicts with a lot of long-lived branches, drives team working and improves efficiency.

Pillars of Trunk Based Development

There are some core pillars that are very important for trunk-based development. Some of them are as follows:

  1. Single Source of Truth—The trunk is the main branch, also known as the mainline or trunk, and is the single source of truth. All changes need to propagate to this at regular intervals. All decisions are taken on this mainline, including cutting for features, deployments, and releases.
  1. Code Review—Reviews are the core of trunk-based development since changes are frequently committed. A robust review process should be in place to enable frequent code merges. Code reviews need to happen to maintain code quality, give confidence, and enhance developer productivity. 
  1. Small, frequent commits – Developers have to follow the process of ensuring code is committed several times throughout the day, advocating frequent commits since trunk-based development emphasizes reducing the merge conflicts, which cannot happen if developers work on code bases for a longer duration and commit large code base at one go
  1. Continuous Integration: As code is committed, an automatic build process gets triggered, which then kicks off an automated test to check for quality. Any failures need to be addressed immediately to ensure the mainline is not blocked by this failure and the mainline’s quality is as per the standard defined
  2. Feature Flags: Features can be rolled out in the production environment without making them visible to the end users for further testing or gradual rollouts. The feature flag helps maintain continuous delivery. Developers can commit unfinished feature code, and using the feature flag, it can be turned off in the production when it is deployed. This basically decouples deployments from releases
  3. Releasable State & Monitoring: The mainline failures are immediately attended to, and the mainline is always in a releasable state, which has gone through a series of reviews, validation, and testing. Continuous monitoring is also crucial, where the feedback is continuously passed, which helps with overall improvement 

Benefits of Trunk Based Development

  1. Speed, improve time to market – As code is frequently committed, reviewed, built, tested, and merged to the main trunk, the code is always in a releasable state. This helps to deliver value to customers much faster.
  2. Improve Code Quality – As trunk-based development emphasizes small, frequent code commits, this only pushes for better reviews, testing, and validation. Any failures in the build should be addressed immediately, and necessary actions need to be taken to keep it working, free from failures, and maintaining the quality to release
  3. Improved Engineering Productivity: Trunk-based development fosters collaboration among developers to ensure they work as a team to deliver value. They collectively own, discuss the challenges, and work together for code reviews. As everyone works in the same branch, they are not isolated; they share knowledge and best practices and improve the product as a team. With this strategy, they have fewer code conflicts, higher code quality, faster releases, and enhanced customer success, which all lead to improved engineering productivity
  4. Lessen Merge Conflicts : As the code is frequently committed and merged with the mainline, the conflicts are addressed much earlier and more regularly. It is easier to fix them, as the code that is committed and merged is frequent and small. Hence, the merge conflicts would also be less and more manageable to address
  5. Improved CICD: The build process kicks off as part of continuous Integration, which makes sure the code is tested, validated, and meets the quality criteria with every commit. Failures are addressed immediately with a fix or rollback. This ensures there are fewer failures and surprises when it is released in production. The most significant advantage is that it runs very often and continuously. The code is always in a deployable and releasable state, which further helps the continuous delivery Or deployment phase. All the integration issues are sorted out much earlier and often to enable a smooth CICD process.
  6. Simplified development workflow: Trunk-based system has one main branch and does not advocate for multiple long-lived branches. With the single source of truth, code repository maintenance and management becomes much more accessible, and the overall development & release workflow becomes simple 
  7. Reduction in Code Drift: There is a risk of code drift when the branches are long-lived, but in trunk-based development, the branches are short-lived, and there are small code changes and frequent commits, which leads to reducing the drift in the code. By decreasing the divergence between the primary and other branches, trunk-based development alleviates the code drift 

Trunk Based Development vs Git Flow

Gitflow is another popular development model with its own branching strategy. The main differences between trunk-based development and other development and branching models are characterized by the duration of the branch’s existence and the frequency of commits.

Trunk-based development revolves around a single shared repository with short-lived branches and small, frequent code commits, while Gitflow development revolves around various separate, long-lived branches. 

For example, Gitflow, on any project, will have various branches, like the Feature branch, in which developers work on a given feature; once work is completed, they will merge into the development branch. Testing is conducted, and once it passes, it will be merged into the release branch and eventually to the main Or master branch

Gitflow offers a structured workflow where branches can be defined based on the requirement. If two software versions have to be supported, then two different release branches must be maintained. It will help to isolate the features, manage releases well.

Which One to Use

While trunk-based development & Gitflow have advantages and disadvantages, which one to choose depends on the needs and requirements of the teams. 

While the trunk might be better suited for teams with frequent delivery, fast-paced agile teams, and projects, Gitflow may be better suited for longer projects, dealing with managing multiple versions and releases for customers. Trunk-based demands a high level of collaboration communication compared to Gitflow.

Overall, evaluate what each model offers and see how it fits in with your overall requirements before you adopt.

Trunk Based Development Challenges

Trunk Development requires a robust testing process, strategy, and tooling. It requires building solid testing and test automation to keep up with the quality standards. Culture of Testing First approach, early testing should be embraced by the whole team. 

A high level of discipline is expected out of the team so that they adhere to practices and processes to ensure the coding, committing, and testing are required at the same level, and the build stays intact.

Directly working with the main branch often has a lot of risks and challenges that could lead to frustration, failures, and reduced productivity if it’s not executed well

As the team size grows, it might be challenging to keep up as it leads to lot of changes, commits, testing, merging and build failures.

How Companies Can Adopt Trunk Based Development

Meticulous planning is necessary for companies to adopt or transition to trunk-based development. Companies can adopt the strategy below.

  1. List down your needs and requirements, what you intend to do, what the challenges are, team structure, goals, and release cycles
  2. Evaluate how trunk-based development fits and what changes need to be brought in to adopt trunk-based development.
  3. The team’s buy-in consensus is critical; ensure you discuss the team knows what they are signing up for
  4. Train the team and ensure everybody has sufficient knowledge and practice to start working on trunk-based development.
  5. Define the process, guidelines, and structure that will be rolled out with trunk-based development. Some examples could be a code review process, a commit process, test drive development, CICD, and a branching and merging strategy.
  6. Implement tooling and infrastructure that is needed for trunk-based development. Also, emphasis on collaboration and communication to drive efficiency
  7. Ensure you have good test automation to complete the required testing at various levels.
  8. Continuously monitor the process, and address the shortfalls and challenges. Monitor, iterate, and fine-tune as you review the key metrics.
  9. Continuous learning and improvement are essential, where teams learn, adapt, and improvise the best practices to drive engineering productivity.

Conclusion

Overall, Trunk-Based development addresses some of the challenges posed by software development and can be a good practice that can be adopted to accelerate the software delivery process, driving company and customer success.

Trunk-based development improves engineering productivity, collaboration, and communication and drives shared ownership across the organization

Organizations can break silos and deliver software that is reliable, of high quality, and at an accelerated pace by embracing trunk-based development.

Written By
Mahesh Mallikarjunaiah
Mahesh is an experienced engineering executive with two decades of leadership and management experience in product engineering, cloud, devops, SaaS, and quality. He has always enjoyed building high-performance teams from scratch. He is deeply passionate about continuous learning and constantly strive to push boundaries, expanding his horizons.
Reviewed By
Michael Mendy
Michael Mendy, one of the most prominent members of the CI/CD community, is a software engineer with Travis CI. He regularly speaks before groups talking about CI/CD, he’s spoken at IBM, droidcon, LeadDev, Arm DevSummit and others.
© Copyright 2024, All Rights Reserved