Lecture
Continuous integration (CI): short-lived feature branches that the team merges into the main development branch several times a day; the build and test processes are fully automated, delivering results within 10 minutes; deployment is performed manually.
Continuous delivery (CD): automates CI plus the entire software release process. It may consist of several stages. Deployment to production is performed manually.
Continuous deployment: CI + CD + fully automated deployment to production.
The abbreviations CI and CD are often used in the context of modern development methods and DevOps. The abbreviation CI stands for continuous integration. It is a fundamental DevOps recommendation whereby developers regularly merge their code changes into a central repository, where automated builds and tests are run. The abbreviation CD, meanwhile, can stand for either continuous delivery or continuous deployment.
Developers who practice continuous integration merge their changes into the main branch at every opportunity. A developer's changes are validated by creating a build and running automated tests against that build. With this approach, you avoid the integration difficulties of waiting until release day to merge changes into the relevant branch.
Continuous integration places a strong emphasis on test automation, ensuring that the application keeps working when new commits are integrated into the main branch.
Continuous delivery is an extension of continuous integration, since it automatically deploys all code changes to a testing and/or production environment after the build stage.
This means that in addition to automated testing, you have an automated release process, so you can deploy the application at any time with a single click.
In theory, with continuous delivery you can release daily, weekly, biweekly, or at whatever cadence suits your business. However, if you truly want to reap the benefits of continuous delivery, you should deploy to production as early as possible, ensuring that you release small batches of changes that are easy to troubleshoot in the event of a problem.
Continuous deployment goes one step further than continuous delivery. With this approach, every change that passes all stages of the production pipeline is released to customers. No human intervention is required, and only a failed test can prevent a new change from being deployed to production.
Continuous deployment is an excellent way to speed up the feedback loop with your customers and relieve the team of unnecessary pressure, because there is no longer a release day. Developers can focus on building software. They see their code go live within minutes of finishing it.
Put simply, continuous integration is part of both continuous delivery and continuous deployment. And continuous deployment is similar to continuous delivery, except that releases happen automatically.

We have explained the difference between continuous integration, continuous delivery, and continuous deployment, but we have not yet looked at the reasons to adopt these approaches. Adopting each of them clearly comes at a cost, but that cost is largely justified by the benefits you gain.
Traditionally, one of the cost items associated with continuous integration has been setting up and maintaining a CI server. However, you can significantly reduce the cost of adopting these approaches by using a cloud service, for example Bitbucket Pipelines, which adds automation capabilities to every Bitbucket repository. Simply by adding a configuration file to the root of the repository, you can create a continuous deployment pipeline that runs for every new change pushed to the main branch.

If you are just starting a new project and do not yet have any users, it may be simple to deploy every commit to production. You can even begin by automating deployments and releasing an alpha version to production without customers. Then, as you develop the application, you will build up your testing culture and increase code coverage. And by the time you are ready to onboard users, you will have developed an excellent continuous deployment process, where all new changes are tested before being released to production automatically.
But if you already have an application in use by customers, it is worth slowing down and starting with continuous integration and continuous delivery. Begin by introducing basic unit tests that run automatically. At this stage, it is still too early to focus on complex end-to-end testing. Instead, you should try to automate your deployments as soon as possible and reach the point where deployments to staging environments are performed automatically. Once you have automated deployments in place, you can focus your efforts on refining the tests, sparing yourself from having to periodically pause to coordinate the release process.
As soon as software releases start happening daily, you can begin considering continuous deployment. Before that, however, you need to make sure that the rest of your organization is ready for such a shift too. Documentation, support, marketing. These teams also need to adapt to the new release frequency. It is important to organize the process so that they do not miss significant changes that could affect customers.

Continuous integration, continuous deployment, and continuous delivery are like vectors that point in the same direction but differ in magnitude. The goal of all three practices is the same: to improve the reliability of software development and releases, and to speed up development and releases.
The main difference between the three approaches is the amount of automation each of them involves. Newcomers often confuse these phenomena because they do not realize that they are not mutually exclusive but nested inside one another like matryoshka dolls.
The core: continuous integration
Most developers who get into the topic first become acquainted with continuous integration (CI), which works as follows: all changes made to the code are combined into a central repository (the operation is called a «merge»). Merging happens several times a day, and after each merge an automated build and test run is triggered for the particular project.
Sometimes, before the build and test run, the program needs to be compiled (this depends on the language it is written in). These days it is increasingly necessary to package the application into a Docker container. Then the automated tests check specific code modules, the UI behavior, the application's performance, the reliability of the API, and so on. Collectively, all these stages are usually called a «build».
CI is a kind of safety net that lets developers avoid a host of problems before delivering a project. As a result, programmers feel more confident submitting such code, but the work itself is unlikely to speed up – deployment may still be performed manually and take a long time, and errors can occur at this stage too.
The most that developers can achieve at the first stage is to make the automated test suite comprehensive and stable enough that any build that has passed CI can be safely pushed first to staging and then to production. This way you can do without lengthy manual testing (QA).
Second, pay attention to the speed of CI: I am convinced that developers should get CI results within 10 minutes at most, otherwise productivity drops because of lost focus and frequent switching between tasks. To speed up CI, it is convenient to parallelize tests on some powerful platform.
Moving on to continuous delivery and deployment
Continuous delivery (CD) is the practice of automating the entire software release process. The idea is to perform CI plus automatically prepare and drive the release toward production. Ideally, you want to achieve the following: anyone with sufficient privileges to deploy a new release can perform the deployment at any moment, and this can be done in a few clicks. Freed from almost all manual work, the programmer works more productively.
As a rule, the continuous delivery process requires at least one step to be performed manually: approving the deployment to production and triggering it. In complex systems with many dependencies, a continuous delivery pipeline may include additional stages performed either manually or automatically.
Continuous deployment sits «one level above» continuous delivery. In this case, all changes made to the source code are automatically deployed to production, without an explicit go-ahead from the developer. As a rule, the developer's job comes down to reviewing a colleague's pull request and keeping the team informed of the outcome of all important events.
Continuous deployment requires the team to have a well-established monitoring culture, with everyone able to keep a finger on the pulse and quickly recover the system.
I have had occasion to talk with many teams that practice continuous deployment. It turned out that developers greatly value the ability to configure deployment for different environments; it is equally important for everyone to understand who deployed what and when. Developers who practice CI and want to move to continuous deployment first automate deployment to the staging environment, while continuing to deploy to production manually – with a single click.
The boundaries of the concepts
Because «continuous delivery» is a more fluid concept than «continuous integration» and «continuous deployment», the first term applies in a broader context than the level of an individual service or application – it can describe the workings of an entire system and even an organization.
For example, you could say that with full-fledged continuous integration, it should be possible, in the event of a failure, to recreate a complete copy of the production environment from scratch – with a single command. Or you might agree that we cannot maintain the required development pace on the team if we do not manage to deploy a new microservice in about 5 minutes. This is exactly where it is difficult to draw the line between continuous delivery and DevOps. Indeed, it makes more sense to leave in the DevOps category such tasks as automated infrastructure provisioning (for which the «infrastructure as code» practice is used), product-wide logging, and metrics tracking.
In addition, confusion sometimes arises about what the abbreviation «CD» means in the pair «CI/CD». There is no clear-cut answer to this question, but in most cases this pair is understood as «continuous integration and continuous delivery». This makes sense, given that continuous deployment is a special case of continuous delivery that is not applicable to every system.
Comments