What is trunk-based development?
Trunk-based development is a software development approach where all developers work in a single branch (often called the "trunk" or "main") rather than creating long-lived feature branches. This method encourages frequent integration of changes to reduce the complexity of merging and collaboration
Key concepts of trunk-based development
1. Single source of truth
In trunk-based development, the trunk serves as the single source of truth for the codebase. All changes are made directly to this branch, minimizing the risk of divergence between branches and simplifying the integration process.
2. Short-lived branches
If branches are used, they are kept short-lived—typically no longer than a day or two. This approach encourages developers to integrate their changes back into the trunk as quickly as possible, minimizing the chances of merge conflicts and facilitating faster feedback.
3. Continuous integration and delivery (CI/CD)
Trunk-based development relies heavily on continuous integration and continuous delivery (CI/CD) practices. Automated tests run on each change to keep the codebase stable and deploy features quickly.
Branch vs. trunk development
Branch development
In traditional branch-based development, developers create separate branches for features, bug fixes, or experiments. These branches can exist for an extended period, which could lead to several potential issues:
- Merge conflicts: Longer-lived branches can diverge significantly, resulting in complicated and time-consuming merges.
- Delayed feedback: Changes might not be integrated until later in the development cycle, which can lead to integration issues and bugs going unnoticed for longer periods.
- Complex history: The commit history can become cluttered with merges and branch-related activity, making it difficult to track changes.
Trunk development
In contrast, trunk-based development encourages developers to work directly on the trunk. This method offers several advantages, including:
- Simplified merging: Since developers integrate their changes frequently, merge conflicts are less likely to occur.
- Faster feedback: Changes are immediately available for testing and feedback, enabling a more agile response to issues.
- Cleaner history: A linear commit history makes it easier to understand the evolution of the codebase.
Git workflow vs. trunk-based development
Git workflow
In a typical Git workflow, developers create branches for new features or bug fixes. They might follow a pattern like this:
- Create a new branch from the main branch.Terminalgit checkout -b feature/my-feature
- Make changes and commit them to the branch.Terminalgit commit -m "Add new feature"
- Push the branch to the remote repository.Terminalgit push origin feature/my-feature
- Open a pull request to merge the changes back into the main branch.
This workflow can lead to the aforementioned issues of merge conflicts and delayed feedback.
Trunk-based development workflow
In a trunk-based development workflow, the steps look quite different:
- Pull the latest changes from the trunk.Terminalgit checkout maingit pull origin main
- Make changes directly on the trunk or on a short-lived branch.Terminalgit checkout -b feature/my-feature# Make changesgit commit -m "Add new feature"
- Merge changes back to the trunk as soon as possible.Terminalgit checkout maingit merge feature/my-featuregit push origin main
- Delete the feature branch to keep the repository clean.Terminalgit branch -d feature/my-feature
Implementing trunk-based development with Graphite Automations
Graphite Automations can streamline the trunk-based development workflow by automating repetitive code review tasks and ensure adherence to best practices. Here’s how to effectively leverage Graphite Automations within this framework:
Automate code review tasks
With Graphite, you can create automation rules that trigger actions based on specific criteria for pull requests (PRs). This capability enhances the efficiency of integrating changes into the trunk while minimizing manual effort.
Setting up automation rules
Automation rules consist of two main components: a filter trigger and an action.
Filter trigger
You can specify filtering triggers for PRs using the filters available in Graphite’s PR inbox. Additionally, you can define glob patterns for filenames, allowing you to target PRs containing specific file types or those in certain directories. For example, you might set up a rule for PRs that include TypeScript files (**/*.ts
) or changes in a designated team directory (**/myteam/**
).
Actions
When a PR meets the specified conditions, you can configure one or more actions to take automatically. Relevant actions include:
- Adding reviewers: Automatically assign reviewers to the PR, ensuring timely feedback on changes.
- Adding labels: Tag PRs with relevant labels to facilitate organization and tracking within the trunk.
- Leaving comments: Post comments on the PR to provide reminders or additional context for team members.
Creating and managing rules
To create and manage automation rules:
- Navigate to Automations: Access this feature from the sidebar in the Graphite web app.
- Create a new rule: Click on "Create rule" and specify the repository for the rule (ensure it's one of your synced repositories).
- Configure conditions and actions: Set the conditions for matching PRs and the actions to be taken automatically.
- Preview and activate: Before activation, you can preview past PRs to confirm your conditions are correctly set. Once satisfied, click "Activate rule" to apply it to open PRs and any future ones matching the triggers.
Note on rule execution
Each rule matches only once per PR. If a PR does not initially meet the criteria, it will be re-evaluated with each update until a match is found. Once a rule is matched, it won’t trigger again on that PR to avoid repetitive actions. Automations only evaluate published PRs and do not apply to closed or draft PRs.
By incorporating these automations into your trunk-based development workflow, you can reduce manual tasks, enforce consistency, and maintain a high quality of code as changes are integrated.
Key takeaways
Trunk-based development offers a streamlined approach to software development by emphasizing integration and collaboration. By minimizing the use of long-lived branches and encouraging frequent commits to a single trunk, teams can benefit from faster feedback, simpler merging, and a cleaner commit history. Coupled with tools like Graphite Automations, this workflow can significantly enhance the efficiency and effectiveness of your development processes.