Lately, I’ve been thinking a lot about helping smaller teams—especially those working with “legacy applications”—modernize their workflows. Working for a Fortune 500 company on an “enterprise-scale” application every day can cause you to take things like Continuous Integration and Delivery (CI/CD) for granted.
With that in mind, I’m going to try to turn my attention to simplifying some of these concepts. If you’ve ever been told “you should be using continuous integration” and been left wondering “okay, but how?” this post is for you!
Understanding Continuous Integration
The term Continuous Integration (the “CI” portion of CI/CD) quite simply means using automation to constantly test your code, ensuring that each change you make can cleanly integrate with the rest of the codebase.
For example, I might add a new function into my application, commit the change, and push it up to GitHub. If I’ve configured a Continuous Integration pipeline (e.g. GitHub Actions), I might have it run all of the following checks on my code:
- Do my unit tests still pass?
- Do my changes adhere to the project’s coding standards?
- Are there any issues that might be detected by static code analysis tools?
All of this happens automatically, each time I push code, with the idea that it’s much less expensive to catch bugs before they reach production than after the fact.
Of course, the more robust your test suite, the more effective CI can be. Still, even without much in the way of automated testing you might set up rules around coding standards, blocking sensitive data from being committed, or even just ensuring that there aren’t any syntax errors in the changed files.
Think of Continuous Integration as Automated Quality Assurance: the more you can automate, the less time you or your team will spend manually testing the code, which means a much shorter feedback loop.
The Role of Continuous Delivery
Continuous Delivery, the “CD” portion of “CI/CD” is the practice of ensuring that your code can be delivered (read: released to production) at any time.
If you’ve been writing software—especially for the web—for a while, you’re probably familiar with the old “edit a file, then FTP it to production” song and dance. For a long time, this is how web software was released (and is likely still more pervasive than industry leaders may want us to believe). While FTP is a rather simple way to get code from your computer onto a web server, it’s highly error-prone because it’s largely a manual process: what happens if a file with syntax errors is transferred? Do the people uploading files know how to roll back changes? How do you avoid file permission issues?
Continuous Delivery helps mitigate these risks by creating consistent, reproducible builds. Instead of individual developers having direct access to production (and the security implications that come with it), a CD service is told “this is how to build the application and release it to production.”
I’ve shared a universal script for atomic deployments, but your needs may vary. The important thing is that Continuous Delivery removes the human element, ensuring that deployments happen the same way for each and every deployment.
Continuous Deployment: the other CD
Sometimes, you may see CI/CD referred to as Continuous Integration and Deployment, which is a slightly different approach for achieving the same goals.
Generally speaking, Continuous Delivery is used to batch up changes: maybe you’re preparing version 2.0 of your software, or you only release changes to production at the end of a sprint. While you could deploy at any time, there’s usually some manual step (often clicking a button) to release the changes.
Continuous Deployment, on the other hand, means that code is released as soon as it’s ready. Depending on the size of your organization and application, this could be as many as hundreds of times a day!
CI/CD: name a more iconic duo
When used together, Continuous Integration and Delivery help you easily release code while also ensuring that it satisfies all of your requirements. Best of all, it does this automatically: if your tests fail, the CI/CD pipeline will prevent the code from being released.
If you’re using a branched version control strategy (which I certainly hope you are!), a good CI pipeline can prevent buggy code from ever making it into your main branch. Once it’s ready and passes CI, CD ensures that it reaches production exactly the way you expect.
Leave a Reply