CI vs. CD Explained by Emoji: Part 1, Continuous Integration
Technological change this century is expected to accelerate at a rate most of us will find shocking. DevOps principles and culture are the de facto standard for innovative businesses. For DevOps to be effective, it must be paired with specialized tools, which is why continuous integration/continuous delivery (CI/CD) has become another driving force for change. But confusion remains about what CI/CD means, the differences between CI and CD, and how they are implemented.
CI/CD covers the software lifecycle from when a developer commits code 🧀🍅🥓🍍 to when that code is released into production. If CI/CD were a pizza delivery business (because why not), it would cover the entire process from putting all the ingredients together for making a new pizza recipe 📃, cooking it, checking its quality, through to delivery to someone’s door.
Admittedly, in this pizza analogy, our “CI/CD Pizza (Git)Hut Company” would be the Amazon of pizza delivery. The company would be working at scale and highly automated. It would have an industrial R&D kitchen with a team of chefs throwing together different ingredients, concocting new recipes and cooking pizzas at a rapid rate every day. Each pizza created from a recipe would be run through rigorous QA testing and verification tests, conveyed along automated belts, boxed and swiftly delivered out the back of the store as piping hot pizza to hungry customers. Essentially, what this tells you about CI/CD is that it thrusts products into production much faster after thorough testing and leaves legacy companies in the dust.
To understand how CI/CD works, you need to know that the continuous integration (CI) component of CI/CD is focused on the development stage. The developers are the chefs in working in a centralized kitchen, constantly experimenting with new ingredients.
CI works on the basis that the latest stable build of the software is available at all times, sitting in a centralized repository. CI also expects our team of developers to be working on the same main branch and frequently making code changes, often daily, that are committed to the main branch. We could describe the stable build as our secret, award-winning-but-constantly-evolving-pizza recipe.
If you like, the code commits are new pizza ingredients that chefs are trying out to produce a fresh and better-tasting pizza. Like code commits, the ingredients can be anything that adds to a product, so a flour mix for the dough could be replaced with cauliflower, for instance, to create a different type of pizza. Similarly, a feature that makes an app work on a different operating system, for example, creates a new artifact that’s centrally stored.
As you would expect, CI has an emphasis on frequent code check-ins, and each check-in is verified by creating and testing 🥄 a new build.
When a developer is ready to commit new code, the usual approach is to pull down the latest stable build 📃, test it locally to ensure it works 🥄, and integrate the new code 🥣 to create a new build. In the same way that an individual chef would taste-test their latest creation, a dev runs their own tests locally on their new creation as early as possible in the process to ensure quality is maintained.
CI tools help automate this agile approach to development and establish a predictable process so developers can work together on the same project. CI automates 🤖 the developer’s testing. (Time for a coffee and doughnut break or a walk in the park.) Once a developer is satisfied, the build is submitted to an integration server. This minimizes code conﬂicts since code is reviewed and tested again on the integration server and any issues are fed back to the team.
As a stable build always exists in a central repository, any code commit can be reverted to the last-known working build if testing goes wrong or an issue arises.
Jenkins is a good example of a CI integration server, as it integrates with many tools and plugins in both the CI and CD ecosystem.
This means it can be extended beyond CI into CD, but CD is an extension beyond its original design — it wasn’t made for cloud deployment, which means that external scripts ✍️ are required.
Read Part 2, where we cover the role of continuous delivery and continuous deployment, the differences between the two, and — stretching our analogy even further — how to make pizzas at scale that are better than mamma used to make.