CD Without CI
Jonathan Hall
I rescue Golang projects written by AI | Sign up to learn about Go every day boldlygo.tech/daily
Conventional wisdom tells us that CI (Continuous Integration) is the necessary first piece to a CI/CD (Continuous Integration/Continuous Deployment) pipeline. Typical advice for adding CI/CD to an existing project goes something like this:
- Write a bunch of automated tests, broadly employing the test pyramid. Aim for 100% test coverage.
- Automate the running of your unit tests for every code change with a CI tool.
- Find some way to instill responsibility and trust into every member of the team.
- Finally automate the deployment process.
In this post, I want to challenge the conventional wisdom, and offer a way to skip steps 1-3, and to do so responsibly, and with even less FUD than the conventional wisdom can offer.
Definitions
Before we get too far into the weeds, let me offer some definitions. CI/CD has some broadly-accepted definitions, but let me put a fine point on what precisely I'm talking about, just to avoid any confusion.
- Continuous Integration
Wikipedia offers a good general definition, but I generally operate on a more specific definition:
Continuous Integration (CI) is the practice of merging all developers’ changes into a shared mainline every time they complete a change.
My definition assumes a trunk-based development approach, but it can also work with many other common workflows.
- Continuous Deployment and Continuous Delivery
These two concepts are often conflated, if only because they often share an acronym (I like to use CDE for Continuous Delivery, to distinguish, and will use this convention from now on). And they are related, but the distinction is often important. Here are my definitions:
Continuous Deployment (CD) is the practice of automatically deploying software into production any time the mainline branch changes.
In contrast,
Continuous Delivery (CDE) is the practice of packaging software into a deployable state any time the mainline branch changes.
An important thing to notice here is that both CD and CDE, by my definition, are triggered by the same event: the mainline branch changing. This means that there cannot be a manual step, even if it's only to press a button, between delivery (packaging) and deployment. If you have an automated deployment script that runs when you hit “Deploy”, that's better than a manual deployment process, but it is not CD!
For most projects, Continuous Deployment should be the goal. This article is about achieving Continuous Delivery, but since Continuous Delivery is a strict subset of Continuous Deployment, it applies equally well to the latter.
Fear, uncertainty and doubt
There are many reasons people cite for not employing CDE (yet). The most common reason I've heard is a lack of (sufficient) automated tests to instill the confidence necessary to automatically deliver software.
This is underlined by the wikipedia article on the subject, which cites (among others), two salient obstalces to CDE adoption:
- Lack of test automation: Lack of test automation leads to a lack of developer confidence and can prevent using continuous delivery.
- Tests needing a human oracle: Not all quality attributes can be verified with automation. These attributes require humans in the loop, slowing down the delivery pipeline.
Other reasons are usually variations on this theme. Let me enumerate a few I've run into over the years:
- User Acceptance Testing must happen before delivery
- Sprint demos must happen before delivery
- The CTO needs to approve all changes before delivery
You're probably noticing the theme here. Every common objection to CDE boils down to essentially one thing: A human must validate the changes before they are delivered.
And this, per se, isn't a problem. What I do see as a problem is the common knee-jerk reaction to this situation:
Then we cannot continuously deliver until our automation is sufficiently advanced to eliminate the need for human validation.
The fear of imperfect automation, and in some cases the dogmatic belief that humans cannot be automated away, is the obstacle to CDE adoption.