Trunk Based Development
In most of the projects, we are using Git flow Strategy which works well if we have a limited number of features in development. Look at the diagram below to understand how Git Flow works
We use Develop as the main branch and cut a feature branch from Develop and once the feature is complete we raise a PR to Develop, the ideal way is that developers should cut their own branch from feature and then raise the PR to feature to make sure that the code is getting properly reviewed. Once the Feature is working fine then the only PR should be raised for Develop branch.
Key Problems with the above approach
Huge pull requests are hard to code review
Hard to review code lets bugs escape
Continuous re-basing and conflict resolution is hard
Let’s talk about the Trunk Based Development
In brief, trunk-based development is where all developers commit to one shared branch (called mainline or trunk) under source-control, resisting the urge to create long-lived branches.
Consider these practices:
Atomic commits. Each commit be one logical unit of change and must not fail a build
Feature flags. Though the commits are checked into the trunk and deployed in production, they needn’t be turned on until the feature is complete. Feature flags are powerful and help you roll-out features in a controlled way.
Since the commit has to be merged into the trunk as it comes in, the review must be done. The review backlog should be never allowed to pile up. To get your team up to speed, it’s essential to establish a culture such that reviewing code is of equal priority to writing code.
Is this worth it? In short, Yes. Trunk based development, when followed consistently, enables the following:
Continuous integration. Incremental commits ensure the code changes are always integrated well.
Flexible feature roll-out. You could roll-out features in a controlled way to say to a specific set of users.
Active code base which encourages better collaboration and clarity amongst the team.
Let’s look at one of the approaches that we have started following in one of our projects
In trunk-based development, developers push code directly into the trunk. Changes made in the release branches—snapshots of the code when it's ready to be released—are usually merged back to the trunk (depicted by the downward arrows) as soon as possible. In this approach, there are cases where bug fixes must be cherry-picked and merged into releases (depicted by the upward arrow), but these cases are not as frequent as the development of new features in the trunk. In cases where releases happen multiple times a day, release branches are not required at all, because changes can be pushed directly into the trunk and deployed from there. One key benefit of the trunk-based approach is that it reduces the complexity of merging events and keeps code current by having fewer development lines and by doing small and frequent merges.
How to implement trunk-based development
Trunk-based development is a required practice for continuous integration. Continuous integration (CI) is the combination of practicing trunk-based development and maintaining a suite of fast automated tests that run after each commit to trunk to make sure the system is always working.
The point of using continuous integration is to eliminate long integration and stabilization phases by integrating small batches of code frequently. In this way, developers ensure they are communicating what they are doing, and the integration gets rid of big merges that can create substantial work for other developers and for testers.
In the CI paradigm, developers are responsible for keeping the build process green—that is, up and running. This means that if the CI process fails, developers must stop what they're doing either to fix the problem immediately or to revert the change if it can't be fixed in a few minutes.
Practicing trunk-based development requires in turn that developers understand how to break their work up into small batches. This is a significant change for developers who aren't used to working in this way.
Analysis of DevOps Research and Assessment (DORA) data from 2016 (PDF) and 2017 (PDF) shows that teams achieve higher levels of software delivery and operational performance (delivery speed, stability, and availability) if they follow these practices:
Have three or fewer active branches in the application's code repository.
Merge branches to the trunk at least once a day.
Don't have code freezes and don't have integration phases.
Ways to improve trunk-based development
Based on the discussion earlier, here are some practices you can implement to improve trunk-based development:
Develop in small batches. One of the most important enablers of trunk-based development is teams learning how to develop in small batches. This requires training and organizational support for the development team.
Perform synchronous code review. As discussed previously, moving to synchronous code review, or at least ensuring that developers prioritize code review, helps to ensure that changes don't have to wait hours, or even days, to get merged into the trunk.
Implement comprehensive automated testing. Make sure that you have a comprehensive and meaningful suite of automated unit tests. and that these are run before every commit. For example, if you're using GitHub, you can protect branches to only allow pull request merges when all tests have passed. The Running builds with GitHub Checks tutorial shows how to integrate GitHub Checks with Cloud Build.
Have a fast build. The build and test process should execute in a few minutes. If this seems hard to achieve, it probably indicates opportunities for improvement in the architecture of the system.
Create a core group of advocates and mentors. Trunk-based development is a substantial change for many developers, and you should expect some resistance. Many developers simply can't imagine working in this way. A good practice is to find developers who have worked in this way and have them coach other developers. It's also important to shift some teams over to work in a trunk-based style. One way to do this is to get a critical mass of developers who are experienced with trunk-based development together so that at least one team is following trunk-based development practices. You can then shift other teams over to this style when you feel confident that the team following this practice is performing as expected.
Ways to measure trunk-based development
You can measure the effectiveness of trunk-based development by doing the following.