Continuous Integration Concept
Continuous Integration concept is a part of Agile Development / Extreme Programming methods. It is a concept that revolves around the use of a code repository and how developers use it.
Martin Fowler article on Continuous Integration is one of the best source for the continuous integration concept. He explained the concept very well.
The easiest way for me to explain what CI is and how it works is to show a quick example of how it works with the development of a small feature. Let’s assume I have to do something to a piece of software, it doesn’t really matter what the task is, for the moment I’ll assume it’s small and can be done in a few hours. (We’ll explore longer tasks, and other issues later on.)
I begin by taking a copy of the current integrated source onto my local development machine. I do this by using a source code management system by checking out a working copy from the mainline.
The above paragraph will make sense to people who use source code control systems, but be gibberish to those who don’t. So let me quickly explain that for the latter. A source code control system keeps all of a project’s source code in a repository. The current state of the system is usually referred to as the ‘mainline’. At any time a developer can make a controlled copy of the mainline onto their own machine, this is called ‘checking out’. The copy on the developer’s machine is called a ‘working copy’. (Most of the time you actually update your working copy to the mainline – in practice it’s the same thing.)
Now I take my working copy and do whatever I need to do to complete my task. This will consist of both altering the production code, and also adding or changing automated tests. Continuous Integration assumes a high degree of tests which are automated into the software: a facility I call self-testing code. Often these use a version of the popular XUnit testing frameworks.
Once I’m done (and usually at various points when I’m working) I carry out an automated build on my development machine. This takes the source code in my working copy, compiles and links it into an executable, and runs the automated tests. Only if it all builds and tests without errors is the overall build considered to be good.
With a good build, I can then think about committing my changes into the repository. The twist, of course, is that other people may, and usually have, made changes to the mainline before I get chance to commit. So first I update my working copy with their changes and rebuild. If their changes clash with my changes, it will manifest as a failure either in the compilation or in the tests. In this case it’s my responsibility to fix this and repeat until I can build a working copy that is properly synchronized with the mainline.
Once I have made my own build of a properly synchronized working copy I can then finally commit my changes into the mainline, which then updates the repository.
However my commit doesn’t finish my work. At this point we build again, but this time on an integration machine based on the mainline code. Only when this build succeeds can we say that my changes are done. There is always a chance that I missed something on my machine and the repository wasn’t properly updated. Only when my committed changes build successfully on the integration is my job done. This integration build can be executed manually by me, or done automatically by Cruise.
If a clash occurs between two developers, it is usually caught when the second developer to commit builds their updated working copy. If not the integration build should fail. Either way the error is detected rapidly. At this point the most important task is to fix it, and get the build working properly again. In a Continuous Integration environment you should never have a failed integration build stay failed for long. A good team should have many correct builds a day. Bad builds do occur from time to time, but should be quickly fixed.
The result of doing this is that there is a stable piece of software that works properly and contains few bugs. Everybody develops off that shared stable base and never gets so far away from that base that it takes very long to integrate back with it. Less time is spent trying to find bugs because they show up quickly.
And expanding on that concept :
According to Martin Fowler of ThoughtWorks, continuous integration is a software development practice that requires team members to integrate their work frequently. Every person integrates at least daily, which leads to multiple integrations each day. Integrations are verified by an automated build that runs regression tests to detect integration errors as quickly as possible. Teams find that this approach leads to significantly fewer integration problems and enables development of cohesive software more rapidly.
This leads to the final detail that makes for successful execution of a CI process. If the idea of continuously integrating is to find issues quickly, thus giving each developer feedback on their work, then there must be some way to evaluate that work quickly. Test-driven development fills that gap. With TDD, you build the test and then develop functionality until the code passes the test. As each new addition to the code is made, its test can be added to the suite of tests that are run when you build the integrated work. This ensures that new additions don’t break the functioning work that came before them, and developers whose code does in fact “break the build” can be notified quickly.
Test Driven Development and the use of Revision Control System (RCS) is important. Together with an automated build server.
Those three components turn Continuous Integration concept into reality.
In summary, Continous Integration is a process that helps create software application that is stable and functional. A process that is very crucial in today fast moving world. The combination of tools and best practices are required to get Continuous Integration concept to real results.