How to Set Up Your CI/CD Branching Strategy
Most organizations today have implemented some form of Continuous Integration/Continuous Deployment to automate stages of development. Having a CI/CD branching strategy can help your teams integrate code easier and find bugs before they are released into production.
Code and CI/CD Branching Strategy
Your code branching strategy determines how and when developers branch and merge. There are several models including mainline, trunk-based development, task/feature branching, and more. When deciding on a method it is important to evaluate what makes sense for your team and product. Most version control systems will let you adopt any of these strategies.
How developers branch code and where/when it gets merged in the CI/CD pipeline are closely related. Branching determines how developers work. CI/CD branches decide how code is built, tested, evaluated, and eventually released.
A basic workflow starts with code being checked out. When the work in the branch is committed, CI/CD processes are triggered. This can be done with a merge or pull request. Then the CI/CD pipeline kicks into high gear.
The goal of CI/CD is to continuously integrate changes to find errors earlier in the process (a.k.a. “shift left”). This increases a project’s velocity by avoiding late stage defects and delays. It creates an environment where code is always ready for a release. Set up your projects and teams for success, with the right CI/CD branching strategy.
Review Your CI/CD Needs
A code branching strategy is the foundation for your team. Your CI/CD strategy determines what actions in a branch trigger a build, test, and/or code review. It also determines how code moves through the DevOps pipeline.
When figuring out your CI/CD strategy, review:
- How many commits are done on an average day by developers?
- How is the build run for each commit?
- Upon success, where does the developers commit go — mainline or master, shared dev codeline?
- When should you run a full build? For example, should you implement a nightly build?
- What is the testing strategy? How much code coverage do you need? Server-side testing? Static code analysis?
- What are your desired metrics for success/failure?
- What are your desired time limits for feedback to the developer?
These questions will determine how you want to structure your branching CI/CD strategy.
How to Structure Your Continuous Integration Strategy
Most teams today want developers to commit several times a day. That way, they go through the CI process and their code is validated before it becomes part of a larger codebase. CI eventually involves merging all developers’ successful commits into the shared mainline or master. For most teams — depending on your size — it means merging at least once a day.
If you are working with a large code base, a nightly CI build may seem like the best option. This build would incorporate all the changes submitted during the day by the entire team. It can verify all of the new code submitted throughout the day doesn’t break the build. However, feedback is limited to once per day, not multiple times per day as code is committed.
On some teams, if this larger build does fail, the model is that “everyone” might get roped in to determine what needs to be fixed before new work resumes. However, many organizations do not want to hold up the entire team’s progress. Evaluate how you can best handle broken builds to keep things moving.
As branches are being merged, it is important to define criteria for how code is then integrated into the main branch. This keeps your DevOps pipeline running smoothly. Your CI/CD branching strategy will depend on the size of your team, complexity of project, and automation adoption.
Code Review and Merge
For all teams, code should be built and tested in an automated way, early and often. This reduces the likelihood of a merge conflicts that result in broken builds or worse. If you are working with a smaller team, you may not need a complex Continuous Integration branching strategy.
The code review process should begin after successful build and test has happened in isolation. Establish criteria and a timeframe for completion of code reviews to prevent bottlenecks. Once the code reviews pass, then merge the new code to whatever branch is determined by your branching strategy.
Basic Continuous Integration
Most teams today use a build runner tool — like Jenkins — to compile and test code automatically. Automating this process involves creating quality gates to evaluate code. If code passes these tests, it is automatically merged into the target branch.
If you have large projects, with many dependencies, a Continuous Integration branching strategy into the mainline or master might not work. You do not want to test your entire mainline for smaller changes. This can create bottlenecks and delay feedback to developers.
If you are using component-based development, this becomes even more complicated. Different components are dependent on one another and need to be tested together.
Orchestrating testing across projects is essential to isolating issues quickly. But you need to shorten the feedback cycles to avoid costly development delays.
Stages for Continuous Integration Branching
For large complex projects with a lot of contributors, teams may use a staging environment. This creates branches separate from the mainline where code can be tested and integrated. These validation environments can speed up your DevOps pipeline and can help protect your mainline.
Staging branches can be used for multiple parts of your pipeline. But depending on which version control system you are using, it may be important to limit them. You do not want to add unnecessary complexity. As code passes tests, it moves to the next stage in the pipeline before eventually being merged into the master.
Using this strategy, you can identify integration issues between multiple features or dependent components before production. Smaller changes can be tested and added quickly. More complex and time-consuming tests can be executed further into the pipeline. This can make testing more effective and efficient.
Sample Stages for a CI/CD Branching Strategy
Let’s create a sample workflow using stage branches. Once a merge request happens, the developer’s code is built and subjected to automated, dynamic testing. If it passes those tests, it is then reviewedThen the code moves into the appropriate stage branch.
The build/integration branch is used to test code with other features and components. It is usually locked down from developers. Merges are automatically made using your build automation tool. If a build breaks, the changes go back to the developers to fix. Using this branch separates issues with the code itself and issues with integrations.
Quality Assurance (QA)
QA branches can run feature, smoke, performance testing, etc. This allows QA to work against a stable branch. And developers can continue to submit changes to development and integration branches. If all tests are successful, the code is ready for the next staging area.
Preproduction code is the most stable in the CI/CD pipeline. This branch should be as close as possible to the master branch. This might be where your nightly CI build takes place. It’s also a great place for a full codebase static analysis to be run, which can take time.
Once release managers inspect the code, the code can be pushed into the master branch and deployed as appropriate for the product you are building.
Managing multiple staging environments can become complicated fast. It is important to communicate this strategy to every person within your organization. Automation is key to making it less complex. As tests are completed, feedback should be delivered back to the team automatically.
How to Manage Your CI/CD Branching Strategy
Implementing a CI/CD branching strategy for your organization has a lot of benefits. It creates a policy for integrating changes quickly, while still ensuring that your code is of the highest quality. It also removes a lot of the confusion about where code should flow.
By integrating changes as smaller units, you can find and isolate bugs faster. To make all of this possible, you need the right tools. And your build runners can only do so much. To set up this level of automation, you need to know what changes are available from developers. With some version control systems, you are relying on them to push changes. Because their branches are often local, release engineers do not have visibility. This means you might miss some changes when running a test.
See into Your CI/CD Pipeline
Keep all your branches organized with Helix Core — version control from Perforce. Using Perforce Streams, your teams always know what changes are available and ready to be merged. Its structure supports complex branching for development and releases (no matter your strategy or size).
With Streams, release engineers can automate staging environments and tests. They do not need to rope in a bunch of code from a variety of different places. It’s because Streams streamlines automation for CI processes. And using the Stream Graph, they can visualize how code is moving through the pipeline. You can even combine Git assets into your pipeline from one single source of truth.
Start streamlining your CI/CD branching strategy using the tools that enhance visibility and allow you to automate easier.