Introduction
Continuous Integration (CI) is a Software Engineering practice that ensures the quality of a software product by running a build after every change of the code. Throughout the years CI has proved to be an essential software development technique. However, not all aspects of CI are relevant for every single software project. Moreover, some people misuse the CI concepts and end up failing to produce good results.
I have recently finished an Industrial Placement at a software design company. This article will present my thoughts on CI based on the experience I gained during my work within the company.
Background
CI is based on daily integration of work from all the members of a team. The aim is to detect errors as early as possible in the development process and fix the bugs immediately in order to reduce project time.
In his article [1], Fowler presents the following main concepts of CI:
- Singe source code repository
- Automated, self-testing and fast builds
- Daily commits to the mainline by all the team members but only after a successful build
- Replicate the production environment in order to test the code
- Make latest deliverables available to everyone
- Automate the deployment
Experience
Given the descriptions of CI many people might think that it is only worth applying it in projects with more than one team member. This is definitely not the case. The project I worked on within the company represented my master thesis. Therefore I was the only developer in the project and I was coding everything myself. Although it took me a while to get used to the company’s version control system (SVN) and their rules I soon realised how useful CI was. I really valued the security of having my code automatically built, tested and deployed. Moreover, by running it on another machine ensured that my code could be safely used and updated by other engineers after my departure.
Although I was assigned an individual project I was still a part of a bigger team which allowed me to understand how they use CI. I have seen that there is no right way to implement CI. In order for it to be successful, its practices have to be modelled with respect to each company, project and team. In his article [1], Fowler presents an optimistic approach to CI and does not talk about the problems that may arise. I will discuss some of these issues that I have observed during my placement.
The project must have some kind of infrastructure before applying CI. But what if the current project is being developed using an older project that didn’t use CI? Many companies (including the one I worked for) use legacy code when developing a new software product. This makes the process of achieving CI even longer and more unpredictable. The most effective solution is to use an incremental approach; start with less frequent builds and increase the frequency as everyone becomes more confident.
The larger the team, the increased overhead in maintaining a CI system. Because of the increased number of developers, the team I was a part of decided to have multiple component CI systems. The project tasks were split between several smaller teams who applied their own CI approach on their work. These sub-systems were used to build an overall system level CI which proved to be more efficient than if there was a single massive system from the beginning.
It is very important for the repository to contain everything necessary for a person to build anything. Test and install scripts, IDE configurations, documentation and many other things must be committed to the mainline especially if the code may be reused in the future. Also, artefacts from old builds can produce false results. Developers must clean the old artefacts before running a new build.
As I said, doing CI effectively involves frequent builds and commits from all the team members. Developers must commit every few hours so that bugs can be fixed quickly and the progress tracked efficiently. However, not all the members of a team have the same level of experience. Graduate students are hired throughout the year so it is very likely that they will end up working on a project that is already mature and applies CI. The solution is to provide systematic training and ensure that everyone has good test coding and build scripting skills.
The worst-case scenario is that people commit just before going out for lunch or before they leave work. This was proven to be a bad practice since it causes many integration errors. Frequent builds and commits throughout the day ensure that the bugs are found and fixed quickly. This also helps increase the moral of the developers since they don’t need to delay lunch and can leave work when proposed.
It is important to differentiate between nightly and weekly scheduled builds and the integration builds. The scheduled builds are usually test builds that take a long time and run even if changes have not been committed. It is advised that developers do an integration build after every change to the mainline. This is because even if a build succeeds it does not mean that software product is working correctly. If later on a full integration build fails it will take longer to find and fix the bug.
Fowler says that builds must be fast but he is not talking about the quality of the final code. If developers rush into building and committing their work it is likely they will not meet the company’s coding standards. It is better if they take their time and make sure that they produce good quality code and save time later on refactoring.
Eric Minick makes a good point in his article [2] where he suggests that Fowler’s article is too focused on build. He says that Fowler should have expanded the scope of CI past build time by emphasising more on the importance of testing. Given my experience within a company I agree with Minick that tests are very important. Most of the employees were verification engineers and a wide variety of verification methods were used. A lot of time and effort was put into verifying the software product and bugs found from running tests were considered a great success. This is because finding bugs proves that the verification techniques are working effectively.
CI was very useful for this project since the customers intended to use the product to create their own. Using frequent integration and bug fixes, small releases could be made to the customers. This allowed them to start their own software projects earlier rather than wait for the final version. Moreover, if the project is late and the customers get impatient, build and bug reports can be sent to them. This way the company is able show the project’s progress and receive constructive feedback.
Communication between the teams working on the same project or between a team and the team leader is also a part of CI. The team I was part of had weekly meetings in which they were discussing the bug and build reports. The progress of each team, interactions between their work and the customer’s input and expectations were reviewed and examined.
Conclusion
Continuous Integration should be a part of each software development process irrespective to the subject of the project or the team size. Although it is a simple concept it is very easy to implement the CI concepts wrong and obtain poor results. Making the builds very fast or too frequent and committing the work at the end of the day are just a few of the bad practices of CI. However, if implemented correctly, CI is an essential part of a successful project.
References
[1] Martin Fowler, “Continuous Integration”, May 2006, accessed February 2014
[2] Eric Minick, “Continuous Integration: Was Fowler Wrong?”, July 2008, accessed February 2014