What is Continuous Integration?
Table of Contents
Developed in 1997, it has now become ever-present and not only a best practice, but a standard one, too.
Building code invariably involves a lot of steps. One way of saving time and effort is through continuous integration, or CI: a way of automating the testing, building and deployment of code.
It helps catch errors early on before they build up to be a major problem, prevents bad code from being published, and as a practice, helps produce higher quality code.
What is Continuous Integration?
Continuous integration (CI) is a software development practice in which programmers integrate their work frequently during the day into a shared repository, usually a version control system.
Ubiquitous to virtually all cloud hosted applications, continuous integration allows developers to simultaneously work on code bases. At the same time, automating the build, test, and release processes helps ensure quality in software development.
Team members integrate code in small chunks and test it in one or more environments. The idea is that teams work on loosely coupled code in short development cycles and can discard code that doesn’t work. Developers merge code into a shared repository several times a day. Each check-in is then verified by an automated build. If the build fails, the developers are notified of the errors and the code is not pushed. If it works, they have saved invaluable time by automating the testing.
In a similar vein, by integrating code with the entire system, continuous monitoring helps detect bugs early, when solving them is least costly.
One of the first things any programmer learns to do is to write programs in a modular way. Each module should be self-contained, so that its success or failure doesn't depend on how other modules work. Add to this continuous integration, and quality of code can drastically increase, and so can the speed at which code is pushed.
There are three main advantages to continuous integration:
First, bad code is detected early on before it snowballs into a major issue. Pushing builds daily, if not more frequently, ensures that time wasted does not typically surpass a day in worst-case scenarios. Moreover, if code written by two separate developers turns out to completely clash against one another, breaking the application, then coders can work on resolving these issues early. Instead of continuing to develop clashing code that would take much more effort to fix.
Secondly, it ensures that bad code is not pushed to a production environment where errors or downtime can severely impact users, reputation, and revenue. Continuous integration builds and updates code in near real time, so programmers can get immediate feedback on what they've done.
Finally, automating the testing, building, and deployment of code saves developers time. They can focus on higher value tasks instead. Oftentimes, automated testing has a much higher return on investment, higher accuracy and reliability, and a faster turnaround time.
Related: Automated vs Manual Testing
All of this ultimately results in the development of cleaner, higher quality code with less technical debt. These benefits directly translate to saved time, higher reliability, a better user experience, and diminishes time spent in the future maintaining, updating, or working on older code.
No decision is without is its drawbacks, and continuous integration is no exception.
One downside of the practice is that merges between branches, or between feature branches of the trunk, are costly. Developers generally have to debug the merge by hand, and this takes time.
Continuous integration should, in theory, lead to better software. The disadvantage to developers, typically in the short-run, should be outweighed by the benefits to customers and the long-run health of the code.
In practice, continuous integration has led to some problems. One of them being that because developers are always working from the same tree, they rarely notice that a tree is getting, so-to-speak, old. Some changes are made, but the tree remains largely intact. Each developer makes his or her own contribution, but the tree as a whole remains much the same. This myopic, close-up view can sometimes lead to losing the bird-eye’s view.
Moreover, because developers work from the same tree, they often run into the same problems over and over. For example, when a method gets overridden, it doesn't always occur to the developer that the method has, in effect, been overridden.
Furthermore, because changes are always being checked into the main repository, developers often lose track of which program they are modifying. If they're working on the wrong one, they waste time.
Finally, and most subjective of all, is that continuous integration can make developers lose track of time. It is often the case that the time saved far outweighs time sunk. Nevertheless, if checking code into the main repository is done routinely, there's a tendency to do it habitually and perhaps, unnecessarily.
Various CI tools
Many large companies use continuous integration tools, such as Hudson or CruiseControl.NET, to orchestrate a complicated series of build and test processes. These systems usually integrate nicely with automated deployment systems.
For small teams, continuous integration tools can be overkill. For small teams, a continuous integration system is best if it has low overhead: a build is triggered whenever someone pushes changes into a version control system, and a build runs automatically every time someone commits. It won't do much more than present the results of the build in a tool your developers can use.
Jenkins is the most popular continuous integration tool. It is free, and relatively easy to install. It integrates well with Subversion, Git, and CVS. It stores its data in a database, which is very convenient if the source control system is MySQL or MongoDB.
You may also set your own continuous integration system inside of GitHub by using GitHub Actions by following this tutorial.
Continuous integration ensures that a multitude of developers can all work together effectively, while minimising the risk that they create clashing code. And if they do, problems can be identified early and solved rather cost-effectively.