CI/CD enables the best tech companies to improve their products many times per day. Here’s what you need to know to do the same.
CI/CD is a way of developing software in which you’re able to release updates at any time in a sustainable way. When changing code is routine, development cycles are more frequent, meaningful and faster.
“CI/CD” stands for the combined practices of Continuous Integration (CI) and Continuous Delivery (CD).
Continuous Integration is a prerequisite for CI/CD, and requires:
- Developers to merge their changes to the main code branch many times per day.
- Each code merge to trigger an automated code build and test sequence. Developers ideally receive results in less than 10 minutes, so that they can stay focused on their work.
The job of Continuous Integration is to produce an artifact that can be deployed. The role of automated tests in CI is to verify that the artifact for the given version of code is safe to be deployed.
In the practice of Continuous Delivery, code changes are also continuously deployed, although the deployments are triggered manually. If the entire process of moving code from source repository to production is fully automated, the process is called Continuous Deployment.
A long deployment process is error-prone and distracting. Developers get frustrated by a process that feels like an overkill. Teams trade small iterations for risky big-bang releases. They may also be led not to make some small improvements at all.
The goal of CI/CD is to make the deployment easy enough, safe and fast. In such context, the probability of introducing major bugs is low. When something bad does happen, it’s easy to deliver a fix or revert the change.
If any developer in your team can stop what they’re doing right now and ship the current development version of code to production in 20 minutes or less without anyone stressing about what could happen — congratulations, you’re doing CI/CD!
Continuous Delivery practices take CI further by describing principles for successful production deployments:
- Architect the system in a way that supports iterative releases. Avoid tight coupling between components. Implement metrics that help detect issues in real-time.
- Always keep the code in a deployable state. Maintain a comprehensive and healthy automated test suite. Build in monitoring, logging, and fault-tolerance by design.
- Work in small iterations. For example, if you develop in feature branches, they should live no longer than a day. When you need more time to develop new features, use feature flags.
- Developers can push the code into production-like staging environments. This ensures that the new version of the software will work when it gets in the hands of users.
- Anyone can deploy any version of the software to any environment on demand, at a push of a button. If you need to consult a wiki on how to deploy, it’s game over.
- If you build it, you run it. Autonomous engineering teams should be responsible for the quality and stability of the software they build. This breaks down the silos between traditional developers and operations groups, as they work together to achieve high-level goals.
To make CI/CD a reality, you need to automate everything that you can in the software delivery process and run it in a CI/CD pipeline.
Here’s a simple example of fully automated CI/CD (Continuous Deployment) pipeline. Nothing shouldn’t be more complicated than necessary!
In this example, each change on the master Git branch performs the following steps on Semaphore:
- Build code and web assets, while reusing dependency cache.
- If the tests pass, a Deploy block updates the production code that runs in the cloud.
Here’s a CI/CD workflow for containers and Kubernetes which includes more steps:
In this example, each change automatically performs these steps:
- Build application from source code and dependencies.
- Run an automated test suite.
- If tests pass, automatically build a Docker container image and push it to a private registry.
At the end of the Docker build pipeline, we have a working artifact, a container image. The developer, or more formally, release manager, can decide to manually trigger:
- Deployment to staging or production, which may include smoke tests to verify no major problems have been introduced.
- Tagging of the container image as an artifact that was introduced to production, to enable audits and rollbacks.
Want more? Read about the benefits of CI/CD and how a typical adoption journey looks like — including when it seems impossible — on Semaphore website.