Recently, I became aware of a trend that has been growing since too long: conflating CI and CD into the same word group - CI/CD. When this is done by marketers, this is business as usual, a mix of buzzwords and hype that shouts "Look at me!". But when this is repeated by professional software engineers, I start to worry. And this is exactly what’s happening right now. This post is meant to be a snapshot of my thoughts that I can refer others to in order to dispel the confusion I believe is surrounding CI/CD.
To do that, a bit of history is in order. In the beginning, there was Continuous Integration - CI, for short. While CI was not strictly a requirement in development projects in the past, it becomes necessary when the project’s headcount goes from 1 to anything above: a single developer can use the file system to develop, and use a simple online storage system to save the progress, automatically or not. However, with just a single additional developer, one runs the risks of overwriting changes made by the other one. For that reason, a new type of software was invented: Version Control Software. However, this only solves the issue of overwriting each other’s source code files.
There’s another issue that comes from multiple developers working on the same codebase. One can introduce changes that are not overwriting anything, but introduce compilation errors or worse - bugs in other parts of the source code. For example, imagine a function used throughout the codebase. Anyone can remove the function, and prevent the code from compiling. To prevent that, one should make sure no changes could have such adverse side-effects. The solution is CI, a way to automate a process to make sure no change breaks the existing codebase.
The exact steps that make up a CI process depends on different factors. For example, a compiled language such as C or Java requires a compilation step. There might be a lot of other steps in a CI process:
- Unit testing
- Integration testing
- Mutation testing
- Source code quality checking e.g. SonarQube
- Packaging: creating an executable, a JAR, a ZIP archive, etc. depending on the technology stack
- Storing the newly-built package in a repository
CI is an age-old practice. I think the first few projects I worked on had no CI, but after that, all of them had it. The real difference is that with time, more and more steps such as the ones mentioned above found their way in.
Now, let’s talk about CD. First of all, let’s mention that CD is built on CI: there can be no CD if there’s no CI. However, CD itself can refer to two related but different things:
- Continuous Delivery
Continuous Delivery is the process of readying a package for deployment at the end of the CI chain. Whether that happens in the regular CI chain, or is triggered by it in another tool, is irrelevant. What matters is that the final deployment to production should be one click (or one command line) away - a no-brainer. This final step of deployment remains a decision from business people.
Continuous Delivery can, but doesn’t need to, include deployments to environments other than the production one e.g. staging. However, in general, this is done for testing purposes: perhaps for integration testing, but more probably for performance testing, and security testing, provided staging is the exact mirror of production.
- Continuous Deployment
Continuous Deployment is one step further than Continuous Delivery. At that point, there’s no "manual" decision involved. A commit triggers the whole pipeline chain, and the final milestone of the chain is the deployment of the value increment in production. Because risks are very high to introduce a bug in production, some safeguards are required: in addition to a lot of testing of different kinds, the deployment itself involves in general some degree of canary releases, so that new version is not made available to all users but only to a fraction of them. Monitoring ensures everything is smooth, at which point the percentage of users benefiting from this new version is increased gradually until it reaches 100%.
Continuous Integration, Continuous Delivery and Continuous Deployment are closely related: they all rely on automation, and the latter depends on the former. However, similarities stop there.
On one hand, I’d advise you to never willingly work for a company with no CI in place, unless it’s to set it up. Nowadays, there’s not a single good reason not to have CI in place. A lack of it is a very bad sign regarding the software engineering culture.
On the other hand, as of now, not many companies do implement Continuous Deployment. And I’m not sure it’s going to change in the near future. Continuous Deployment requires high levels of maturity in many different domains: maturity in automation processes, maturity in testing processes, maturity in the trust between tech and business people, etc.
I hope by that now, you’re are convinced CI and CD shouldn’t be conflated into a single word group and used indiscriminately.