Continuous integration (CI) is the practice, in software engineering, of merging all developer working copies with a shared mainline several times a day. […]CI was originally intended to be used in combination with automated unit tests written through the practices of test-driven development. Initially this was conceived of as running all unit tests in the developer’s local environment and verifying they all passed before committing to the mainline. This helps avoid one developer’s work-in-progress breaking another developer’s copy. If necessary, partially complete features can be disabled before committing using feature toggles.”
One of my favorite questions to ask other software engineers and project managers is, “How do you implement continuous integration where you work?” The answers usually vary based on specific tools and technologies, but they fall into two categories. The first category includes a list that includes most or all of the following:
- An issue tracking tool.
- A tool to handle revision control.
- A code review process or some way to bless what gets merged to the mainline.
- A continuous integration server that …
- Automatically builds the solution at every commit.
- Automatically runs the unit tests on the completed build
- An improvement to the automation to building and testing the solution by automating deployment of the artifacts of compilation.
- An improvement to the automated deployment process by deploying to a simulated production environment for testing.
(Note: in my opinion, if you don’t have at least 1-4 implemented, you’ll have to argue pretty hard that you have implemented continuous integration at all.)
The second category of answers is simply the phrase, “We haven’t found a need for continuous integration yet.” My response to this is to quietly stare at them, wide eyed, hoping that they will follow up with, “but we have full intentions to implement some sort of continuous integration by X date.” This unfortunately never happens and, as the uncomfortable silence continues, I awkwardly back away into the shadows in an attempt to avoid association with these fools.
The interesting part of this equation is that most everyone understands that numbers 1-3 in the list above are necessary. Not only that, but those who haven’t implemented numbers 1-3 are looked down upon and most developers run far away from any job with an organization that doesn’t track issues, use revision control, or participate in peer code reviews. I wonder at times why some still think that the step up to 4 is so difficult. Perhaps it is similar to the aversion to process that Kate Heddleston describes in her article “The Null Process.” She says, “When people say they don’t want process, what they’re really saying is they don’t want formalized process. There really is no such thing as ‘no process.’ A process is simply the steps it takes to complete a task, so if a task is completed then by definition a process was used.” Maybe continuous integration is too much of a formalized process for some to handle, so they implement what Heddleston calls a “null process” instead of the highly formalized continuous integration process. In the end each and every development team performs the same functions before deployment. Code still needs to be merged, built, tested and deployed. The difference here is whether it is automatic and on every commit, or once every time the team deploys to production.
The step to get to number 4 from number 3 in the list is to set up a continuous integration server. My category two friends would probably retort, “That probably costs a pretty penny.” The only 2 continuous integration servers that I have heard being used in practice are Jenkins CI, which is open source, and Continuous Integration with Team Foundation Server, which you are probably already paying for if you develop on a Microsoft stack. The only investment that needs to be made to set up a continuous integration server is time. Even more impressive is that the investment is front-loaded. The time cost of a continuous integration server is mostly in the initial setup. Maintenance is minimal and for the most part you can forget that the server is there until a unit test fails or you want to adjust the process.
I cannot excuse foregoing a continuous integration server for many reasons. If the steps for integration are being executed manually, the integration cycles are most likely spread far apart and, because of the time between each cycle, are excruciatingly painful. If the code is compiled and tested at every commit, minor coding errors and bugs introduced by the commit can be handled quickly, right when they become part of the source, instead of at the list minute when the code should have been in production an hour ago. I have experienced this and too many concessions are made under these types of time constraints. Some of the worst development sins I have committed arose from exactly this situation. My other two reasons for running far away from those who have no plans to implement continuous integration are my biggest arguments for implementing this wondrous process. They are number 5 and 6 in my list above.
There is nothing more satisfying that having the ability to click one button and have a product that has been tested and is available to ship within an hour. Consider this scenario. Your project manager says that you need to ship by the end of the week. You click a button and within an hour you have deployed operational software to QA and they are testing it. 24-48 hours later QA blesses the current build. You click another button and an hour after that you have the production copy of the software ready for the client. This means that you have the rest of the week to focus on the next release. If you don’t believe me, check out what Reid Evans did over here. He set up his Jenkins CI server to do all the steps above with one button click.
If you are having trouble attracting the best candidates to you organization or even decent candidates to your organization, consider continuous integration as a practice that you should adopt. The best candidates will help you implement it, because to them continuous integration is not an option.
TL;DR – I will run far away from any job where, for whatever reason, Continuous Integration is not embraced as a key to the software development practices at that organization. The headaches avoided and the time saved by automating building, testing, and deploying the code are happily avoided by doing so.