What is continuous integration?
Continuous integration (CI) can be considered as an alternative to feature branching. To put it simply, this process occurs when teams integrate their codes on a continuous basis into the shared branch or mainline paving the way for instant feedback.
In this case, trunk-based development enables continuous integration or in other words, it enables teams to merge small changes more frequently into the main codebase or trunk, potentially several times a day. Trunk-based development essentially provides developers the means to divide their work into small batches and then merge their work into the trunk or mainline at least once a day. Meanwhile, feature branching can take days or weeks of work as developers make changes to long-lived branches and do not merge the branch until a feature is complete.
Build automation is one of the major prerequisites for continuous integration. Each integration made by a developer is verified by an automated build to detect any errors. A build tool thus will handle delivering the software in an automated way. In other words, each commit made by a developer should trigger a series of automated tests to ensure the quality of the code. These automated tests should give you an indication that your software is working as it should. There are an array of tools to choose from depending on your needs including Jenkins, Travis CI, Circle CI, TeamCity and CodeShip.
Benefits of CI
Faster deployment
Consequently, this technique allows developers to move fast. Unlike in feature branches, the master branch in the trunk-based development is the only long-lived branch while all the other branches have a limited life-span, reducing merging conflicts since no branches are hanging in development for too long. It allows for quicker feedback too, almost immediately, so there is increased transparency among developers instead of waiting for weeks on end for developers to integrate their changes from a private branch.
Risk mitigation
When developers continuously integrate their changes into the mainline, it’s much easier and faster to detect bugs and eliminate them from your code. Therefore, your chances of releasing a more stable feature with less bugs leading to a significantly improved product that is always ready to release. It also reduces the risk of merging long-lived branches that give rise to conflict and what is known as ‘merge hell’.
Higher quality releases
Continuous integration is essential if you want to release new features and make small changes quickly while helping to minimise what is known as ‘merge hell’ that often results from long-lived branches. As previously mentioned, with continuous integration, bugs can be detected much quicker since continuous changes are taking place resulting in increased efficiency and productivity.
This means that the quality is vastly improved as changes are continuously made and you’re not waiting for everyone to be finished to integrate your changes allowing you to check your code more frequently resulting in greater confidence when releasing your new features.
Drawbacks of continuous integration
The main challenge with this kind of practice is that due to the frequent changes that are made, developers may be tripping over one another to integrate their code at the same time which may lead to increased waiting times. This practice also requires constant monitoring to quickly address any issue that arises. Nonetheless, it is certainly useful when you are looking to release new products quickly and safely.
Continuous integration and continuous delivery vs. continuous deployment
We often see the terms continuous integration and continuous delivery used together. In fact, the two go hand-in-hand where they are often referred to together as ‘CI/CD’.
For continuous delivery to take place, you need continuous integration. As such, continuous delivery comes into play to enable the automated delivery of the integrated code from development to production stage.
With continuous delivery, you are preparing the release for delivery on a frequent basis. Hence, code is delivered several times a day. It is responsible for testing the code and ensure it is delivered without bugs or delays by sharing any changes with a select number of users to get their feedback before these changes are rolled out to all users.
Consequently, CI/CD represent the process of continuous development, testing and delivery of new releases.
The final stage of CI/CD is continuous deployment, often confused with continuous delivery. However, continuous deployment means that any changes made to the code base is deployed automatically to production whereas continuous delivery prepares the feature to be released to production but the when is not done automatically but dictated by the team. Taken together, all of these practices make any release a much less risky endeavour.
CI and feature flags
There might be instances where one developer may have completed their changes and have integrated these changes into the mainline while another developer’s work is not yet completed. An issue arises where the feature cannot be released until all the developers have completed their changes possibly causing delays to the integration process. Here, the conflict can be resolved by merging all changes including unfinished ones but without exposing the half-changing changes.
This can be done using feature flags, which helps enable or disable parts of the code so the feature will be off if it is incomplete. You are essentially placing these unfinished changes behind a flag until it’s ready for release. Then, once this change is ready it can be turned on with the simple switch of a button. Therefore, the use of feature flags in such a scenario helps keep the branch healthy
Final thoughts and best practices
Continuous integration, then, allows for frequent deployment. It enables you to get your releases out to your consumers quicker and to get more feedback on these features. It also smoothens the collaboration process between developers increasing productivity and the quality of their releases.
We will end this article with some CI best practices to check whether your team is really practicing CI, as listed by Martin Fowler from his comprehensive article about CI:
- Maintain a single source repository
- Automate the build
- Make the build self-testing
- Commit to the baseline everyday
- Every commit should be built
- Fix broken builds immediately
- Keep the build fast
- Test in a clone of the production environment
- Make it easy for anyone to get the latest executable
- Everyone can see what’s happening
- Automate deployment