From CI to CD
When delivering software to our customers, the customer assumes that it runs reliably and without significant problems. Any misfunction or outage of the software—depending on its purpose—might lead to a loss of reputation on the customer side and the people and company that developed the software. Think of an issue where code was written weeks or months ago, the software is already deployed in the customer’s environment, and it crashes randomly after some time. While troubleshooting, we might tackle the following issues:
- Time pressure: As the software has already been delivered to production and customers have been affected by its misbehavior, it is obvious to provide a resolution during this process. As people providing this might work under pressure, it’s not unlikely that new issues might be introduced.
- Determine which change introduced the misbehavior: In our case, the change might have been introduced a long time ago, so one of our major challenges might be finding out when or in which context the change has been introduced.
- Finding the needle in the haystack: Our software might consist of lots of components. If we can’t find out which change introduced the issue, we might want to find where in the code it happens.
- Dev/prod parity: As our working copy of the code might already have progressed further than the version we are fixing the issue for, we will also have to update newer versions of the software.
These are only examples of problems we might face while fixing such issues. To tackle such cases, we want to find problems in our software very early and build automation around building, testing, and publishing artifacts, called CI. The process of CI should ensure that the code checked in is continuously built and tested. Therefore, problems are found at a very early stage.
Using CI and CD methods, we can find problems early and avoid them hitting the customer’s system. Before we dive deeper into CD processes and implementation, we will take a brief look at the building blocks of a typical CI/CD infrastructure:
Figure 1.1 – Building blocks of a CD infrastructure
In current development setups, developers store their code in source code management (SCM) systems, such as Git, Mercurial, or Subversion. CI systems, such as Jenkins or Tekton, can either watch these repositories for changes on specific branches or tags or get triggered by the SCM systems to initiate workflows. These workflows may include static code analysis steps, such as linting and static security checks, before building, but also more dynamic tests, which can only be done against the running system, such as API tests or Dynamic Application Security tests.
Usually, these steps run on every commit in so-called feature branches. At some point in time, a developer might decide that a developed code part (feature) might be finished and therefore include it in the shared code base and raise a pull or merge request. As a best practice, there might be code reviews for this integration step, which can be automatic or manual. Humans will do the manual part. Furthermore, automatic checks can be done by a CI workflow, which should ensure that the code checked into the code repository is not only compilable but also stable and, in the best case, secure.
Depending on the release strategy, a successful merge to a central shared repository could trigger the CD process. This could also be done when the code is merged into specific branches or with defined tags. As discussed in later chapters of this book, the code will be deployed in various environments (stages) during the further CD process, and tests should ensure that the software is in a deployable state at the end of the process, and that deliverable artifacts are available. Although the terms CI and CD are often used interchangeably, the process of deploying automatically to the production systems is called CD.
In this section, we learned that it is important to find problems in software early by building and testing software continuously. Furthermore, CD helps us keep the software in a deployable state at any time. Last but not least, CD can help us in accelerating our time to market by deploying to production automatically.