Continuous Integration

Continuous Integration

Presumably, you have integrated Git into your individual undertakings to assist in their management. Its utilization is highly advantageous in averting potentially catastrophic errors. Notwithstanding, the full extent of its benefits materializes when Git is employed in concert with a centralized repository, affording the opportunity for an entire team to collaborate.

However, while the advantages of Git are amplified in a team setting, numerous frustrations also emerge. If you lack industry experience, you may not have had the occasion to experience the "pleasure" of collaborating on a shared Git repository with a team. In the event that you have not, permit me to recount a personal anecdote regarding one of my more exasperating experiences of team collaboration on a shared codebase.

Continuous Integration Saves the Day

It is likely that you have surmised the existence of a superior methodology for software development, hence our discussion on this topic. Continuous Integration (CI) is a technique that can help prevent scenarios such as the one described earlier. The concept of continuous integration was first introduced by Grady Booch in 1991. Booch believed that numerous internal releases were necessary, which were not intended for external distribution. At that time, it was not uncommon for individual developers to work on project portions for extended periods without integrating their work with the rest of the team.

CI has evolved considerably since the last century and has been incorporated into a significant portion of developmental workflows. Much of its popularity is due to Extreme Programming's advocacy of the concept. Extreme Programming is a form of Agile development that emphasizes the need for frequent releases, which can be demonstrated to customers for feedback to inform the next phase of development. This necessitated multiple codebase changes to be checked-in daily.

What is Continuous Integration?

The central objective of Continuous Integration (CI) is to enable numerous developers to work concurrently on the same codebase. While Git permits multiple developers to collaborate on a codebase, several CI solutions employ Git and other version control systems extensively to attain their objectives. It is preferable to conceive of CI as a set of guiding principles that govern how to manage a team working on a shared codebase rather than viewing it as a specific tool or framework. What, then, are these guiding principles?

Continuous Integration Principles

Although most CI workflows share common elements, they can vary significantly.

  • Use a VCS like Git to maintain a central codebase

    It makes sense to use a VCS when working on a team. It allows for easy tracking of who is responsible for which changes. It also makes "undoing" mistakes very easy. What makes CI's use of a VCS is that the repository must include everything required to actually build the software (keep reading to learn why). Also, some approaches, like Extreme Programming, actually discourage using different branches because it means maintaining multiple versions of the software. Extreme Programming stresses that changes should be made to the "baseline" (i.e., master branch) to prevent divergent versions from emerging.

  • Building the software should be automated and easily triggered

    There needs to be a way to initiate a fresh build of the software. This can be for testing purposes (see below) or even deployment. It needs to be automated to prevent developers from having to stop their primary work: improving the software.

  • Once built, the software should be able to test itself against a provided test suite

    If we are going to expend the resources/time to build the software, we should test it. This testing should be automated for the same reasons the building should.

  • Everyone needs to commit work to the shared codebase at least once a day

    This is perhaps the most crucial tenet of CI. One of the primary goals of CI is to reduce the amount of "broken code" that arises. By checking in frequently, each developer has to reconcile their local code with the central repository. This helps prevent situations where one developer works in isolation for days or weeks, and his version of the codebase gets wildly out of date. This can result in code that can't be successfully merged and must be thrown out.

  • Every commit to master should be built and tested

    Again, CI wants to avoid "broken code" as much as possible. One way it accomplishes this is that every time changes are made to the central repository, the software is automatically built and tested. Some workflows will not allow any changes to be made to the shared codebase if these tests do not pass.

  • Mandatory Code Review when requesting changes to be merged into the shared codebase

    Many CI workflows don't allow just any developer to merge their changes into the central repository. Instead, each developer makes a "pull" request to the central repository, which triggers a build and then runs the test suite. Only if the tests pass will the request be processed and forwarded to someone to conduct a Code Review. It is also possible to set up CI to perform an automated style code review using something called a Linter.

Continuous Integration & Continuous Deployment

Have you noticed that you receive updates for certain apps almost daily? How are these developers able to produce production builds so often?

"Traditionally," when a team wanted to release a new version of the software, they would have to build a release candidate. This would be a special build of the software that was determined to be feature complete and would be sent to a Quality Assurance team. Over the course of weeks, the QA team would test the software to ensure it met the specifications and was bug-free. Once this process was done, only then would the software be released to the client/consumer.

Testing can and should, be done throughout the development process. This helps reduce or even eliminate the need for a QA team. With CI, this trend is amplified: each commit is a mini QA process.

So, during the CI workflow, we both build and test our software. What stops us from releasing this verified build to the client/consumer? More and more companies are beginning to realize that there is very little reason not to be constantly releasing new builds out into the wild. This is called Continuous Deployment and really isn't possible without Continuous Integration.

Sample Workflow

Please note there are as many ways of using CI as there are hairs on your head. The breakdown of a workflow that follows is meant to be very generic. If you encounter CI in the wild, it will not fit into this workflow nicely. Remember, CI is a set of guiding principles that can be mixed and matched as required by a given team or project.

  1. An individual developer is tasked with adding a feature or updating the code in some other way. The developer either creates a new branch or works directly on the baseline (à la Extreme Programming).

  2. The developer will likely be using some form of Agile, so will follow a TDD approach. These tests can be incorporated into the larger testing suite in the shared codebase.

  3. Once the feature is complete and passing tests locally, the developer is ready to add their changes to the shared codebase.

  4. For teams that require a Code Review before changing the central repository, the developer will issue a pull request. This will trigger a build and the running of the test suite. If everything is successful, then other developers will be notified that the changes are ready for review. If everything looks good, those changes will be added to the project. If a team doesn't require a Code Review, the developer's commit will still trigger a build and the running of the test suite. If successful, these changes can be automatically incorporated into the project.

  5. Successful builds can be staged for QA review or even automatically deployed (see above).

  6. Repeat!

Continuous Integration is a set of guiding principles that enable multiple developers to work together on the same codebase. While Git is useful for team collaboration, CI automates the software building, testing, and merging process to prevent errors and broken code. CI workflows involve using a VCS like Git, automated building and testing of the software, committing work to the shared codebase at least once a day, and mandatory code review before merging changes into the central repository. With CI, testing can be done throughout the development process, making it possible to produce production builds faster.

Did you find this article valuable?

Support Ravindu Udugampola by becoming a sponsor. Any amount is appreciated!