Long ago, in the dark times*, teams of developers would each work on their own features until it was time to integrate into a product. In the Integration Phase, the changes from tens or hundreds of developers would be merged into a common code base which would fail to compile due to conflicts. And so, the developers would enter in to Integration Hell. Sometimes they would emerge victorious. Other times the project would fail causing much weeping and gnashing of teeth.
Fortunately, we learned that by bringing pain forward and integrating more frequently, we could avoid Integration Hell. In the 90s the daily build became normal and by the early 2000s we had taken this principal to the extreme: integrating continuously and validating those integrations with a fast build and unit test.
Since then, continuous integration has often been conflated with continuous build. Looking at Martin Fowler’s current introduction to his seminal article on the continuous integration, it’s easy to see why:
Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily – leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible.
Meanwhile, our architectural approaches have been changing. Many organizations have been moving away from large monolithic applications for some time. Instead, they are using smaller and smaller components that interact at run time. Service Oriented Architectures (SOA) are a classic example.
So, while we were adopting continuous build techniques to validate that our changes didn’t conflict with fellow developers, we saw fewer and fewer fellow developers contributing to the same builds. Instead, the focused their work on related components. Continuous build has become less relevant. That said, it’s also easy and I wouldn’t write even a toy application without setting it up in a CI tool.
Integration Hell still haunts us and swallows projects. The smaller components that are interacting at run-time are now the critical integration problem. As in the past, we often make the mistake of developing our own portions in isolation, and having an integration phase of our application lifecycle. We even name our test environments things like “System Integration Test”.
The good news is that we know the pattern for solving our recreated Integration Hell. We need to continuously deliver the bits to be integrated, integrate them, and validate with testing. However, we now deliver not just source code changes, but the resulting builds and packages. We validate not by merely building and running unit tests, but by also deploying and running automated integration tests. It is composite applications and releases rather than builds that are certified.
“Integration” now means that we integrate our run-time components continuously. That is where the most critical learning is, and so we must bring it forward and do it continuously.
* If your team has not escaped the dark ages, I’m truly sorry.