A lot of times I use (or hear) terms that we all assume everyone understands. Let’s remember our fundamentals and define CI/CD for future reference.

In my day-to-day work, I see ( and use) the phrase “CI/CD pipeline” a lot. But if someone asked me to describing it, I would struggle.

This week in a meeting with some folks I don’t meet with very often, someone used the terms “CI” and “CD” and it confused the hell out of me. Not because they had used these terms incorrectly, but because I had to think about the terms and what they meant. In my head there was this little conversation going on:

Okay, he just used the term “CD”… what does that mean in this context? Continuous Delivery? Continuous Deployment? What is he trying to describe? Oh, now he used the term “CI”. Continuous Integration! I know that one. But what is he driving at?

This internal conversation was very distracting and took me out of the actual conversation. It was because I didn’t have a clear understanding of these terms. I decided I needed to brush up on the fundamentals a bit and make sure I had a clearer understanding of these concepts fresh in my mind.

What does CI/CD mean? What is a CI/CD Pipeline? Why should I care?

CI/CD is an abbreviation for Continuous Integration/Continuous Delivery and in my opinion, NOT for Continuous Integration/Continuous Deployment.

Continuous Integration

Continuous Integration is a software engineering practice of integrating changes into a shared main branch of code multiple times per day. Each integration is verified by an automated build (including tests) to detect errors as soon as possible.

In the book “Continuous Integration”, Duvall, Matyas, Glover 2007, the practice is simply defined as

“Build Software at Every Change”

I first read this book in 2007 when it first was published. I had experimented with automating builds on several projects. At the time I used NAnt to create build scripts for .NET projects. We had installed CruiseControl.NET and it was a great feeling knowing that if anything failed to build, we would know about it very quickly. But it was not really Continuous Integration. We didn’t commit changes to the main branch multiple times per day. We didn’t have many, if any, unit tests that could be run automatically.

The book was a great introduction to the concepts and principles for Continuous Integration. It started me on a journey of constantly improving this aspect of my work. Today (in 2024) I can’t imagine not practicing Continuous Integration. We have automated builds whenever someone check in their code. I am constantly striving to merge my changes into the main branch at least once per day. Every code change should have supporting tests, and these tests are run automatically with every check in. I have learned to include other verifications with each integration, including code coverage and code complexity metrics, security scans and enforcing coding standards.

Continuous Delivery

Continuous Delivery is a software engineering practice of getting changes into production in a quick, safe and repeatable manner. Central to this practice is the deployment pipeline which automates the steps to build, test, deploy and release software changes.

Jez Humble and Dave Farley wrote “Continuous Delivery” in 2010. It was a great companion to “Continuous Integration”. It described the benefits of a continuous delivery of changes and how to achieve it. I have re-read the book many times and always find new insights to incorporate into my daily work.

But if I had to define Continuous Delivery to a fellow developer, I’d struggle. Let’s fix that. Here is my working definition:

Continuous Delivery is the practice of deploying changes to production in a safe, repeatable manner, on demand. You achieve this goal using an automated deployment pipeline that builds, tests and deploys the code directly from the version control system. Everyone is responsible for ensuring the code is always in a deployable state.

I like this definition because it highlights what I feel are the most important aspects of continuous delivery:

  • deploying code changes is done automatically (ie. no manual steps, except for perhaps approvals)
  • deploying code is done from the version control system (not from something built on a developer’s machine)
  • everyone must focus on ensuring the code is always in a deployable state.

Summary

Going through this exercise of re-affirming my understanding of the terms “CI” and “CD” was very helpful. It highlighted for me the importance of knowing the fundamentals of software development. Also, it is important to ensure everyone participating in a discussion is understanding the use of the terms and are on the same page. When I think back to the meeting, at the time, my mental model of “CI” and “CD” was so scrambled that I should have asked the other participants to clarify what they meant when using the terms!