Single branch for all code (Trunk based development)
Table of contents
Main idea
The idea behind this model is to have a single branch for all code, including different environments like staging and production. This way, all code changes are in one place and always in a deployable state.
One of the key benefits of this approach is that it simplifies the code review and testing process. Developers can easily review each other's code and ensure that it meets the team's standards. It also promotes a continuous integration and delivery (CI/CD) workflow, allowing code changes to be deployed as soon as they're ready.
When something goes wrong
In the event that something goes wrong during testing, such as a feature failing, the team's strategy should be to isolate and fix the problem separately so that it doesn't hold up other code changes from being deployed. Additionally, when a bug arises that's more complex than anticipated, it's important to quickly assess its priority and make sure the necessary resources are allocated to fix it.
Trunk-Based Development is a proven and effective approach for software development that can streamline the process and increase efficiency. It is important, however, to have a plan in place for when things don't go as planned.
When working on long-lived feature branches, the task of refactoring code can quickly become a nightmare. The thought of a difficult merge can even prevent a team from making necessary improvements to the codebase. On the other hand, using Trunk-Based Development allows for easy and frequent refactoring because of the closer collaboration between developers.
No "WIP" commits
This type of development promotes incremental development. By breaking down work into small, manageable chunks, the risk of disrupting the entire codebase is minimized. Plus, if something goes wrong, it's easier to identify and fix the issue quickly.
Every commit made on the main branch should be a working version of the software that is close to being ready for release. This provides a lot of flexibility when it comes to deciding when and what to release.
Feature branches
it's possible to use short-lived feature branches for code review. However, there are a few guidelines to follow in order to maintain a streamlined workflow:
- Feature branches should be kept short, ideally a few days or less.
- Only one developer should be committing to a given feature branch.
- Feature branches should be branched from the main branch and can only be merged back into the main branch.
- The feature branch can only be merged into the main branch once, signaling the end of the feature branch.
- Merging the main branch into the feature branch to keep it up to date with new changes is allowed at any time. It is highly recommended to keep the feature branch fully up to date with the main branch and ensure that it builds properly before merging back into the main branch.
Parameterized CI/CD
Using parameterized CI/CD can be an effective tool to support Trunk-Based Development workflow. By utilizing parameterized CI/CD, different environments such as staging and production can be deployed using the same codebase and branch.
One key benefit of parameterized CI/CD is that it enables teams to test and deploy code changes in different environments without the need for separate branches. This simplifies the process of code review and testing, promoting a more efficient workflow.
Additionally, parameterized CI/CD allows for the use of different settings files or environment variables for each environment. This makes it possible to test the same codebase in different environments and ensures that the code changes are deployed with the appropriate settings. This can be critical when deploying to production, as it ensures that the code changes do not disrupt the functionality of the live application.
Another advantage of parameterized CI/CD is that it facilitates the ability to roll out features to a subset of users, testing it with a small group of users and monitoring the results before rolling out to the whole user base, this feature is often referred to as "Canary Deployment"
For example using Jenkins we can use "Build with parameters", and define the parameters in the Jenkinsfile like this:
pipeline {
agent any
parameters {
choice(name: 'ENV', choices: ['production', 'staging'])
}
stages {
stage('Build') {
steps {
// Build the solution
}
}
stage('Deploy To Staging') {
when {
expression {
params.ENV == 'staging'
}
}
steps {
// Staging deployment steps
}
}
stage('Deploy To production') {
when {
expression {
params.ENV == 'production'
}
}
steps {
// Production deployment steps
}
}
}
}
In summary, using parameterized CI/CD in conjunction with Trunk-Based Development can be a powerful combination that simplifies the process of code review and testing, promotes a more efficient workflow, and enables teams to test and deploy code changes in different environments with different settings and variables.
Resources
- Learning Notes
- Trunk Based Development
- Long-Running Branches Considered Harmful
- Why Code Reviews Hurt Your Code Quality and Team Productivity
- SemanticConflict
- Feature Toggles (aka Feature Flags)
- Branch By Abstraction