While working, developers often have to update their services and deploy them. When the number of projects is small, it's no problem because releases and deployments are rare. Tests are run manually. But when the time comes, the number of services and tasks increases, and it takes more time to complete the same task.
Let's look at the typical process of feature implementation/bug fixing for the majority of projects:
- Get task from backlog/team lead
- Create a new branch from git
- Implement feature, write unit tests to cover new functionality
- Run tests, linters, etc
- Create merge request and wait for code review
- Merge branch to master
- Build an application
- Deploy new build
This process is repeated for every task.
If it takes 10 days to implement, debug and test functions and 1 hour to assemble/reinstall, it seems reasonable and not costly. But if you have a hundred tiny errors for one minute each to fix and go through the whole process, it seems to be expensive. But you must go through it, to make sure that you don't introduce additional bugs. This is what maintaining quality is all about.
The goal of the Continuous Integration process is to establish a consistent and automated way to build, package and test applications. Regression tests provide feedback to developers that code changes did not break the application. With consistency in the process, teams are more likely to make more frequent changes to the code, resulting in better collaboration and software quality. The result of the CI process are tested artifacts of the application.
Continuous Delivery starts where the CI finishes. The CD automates the deployment of applications in selected environments. Most teams work with multiple environments different from production, such as development and test environments, and the CD provides an automatic way to publish changes to them.
Continuous Integration and Continuous Delivery require continuous testing as their goal is to provide users with working applications and quality code. Continuous testing is often implemented as a set of automatic regression tests, performance tests and other sorts of tests that are performed in the CI/CD pipeline.
In mature CI/CD practice has the CD process where all code changes are passed through the CI/CD pipeline and deployed directly in the required environments after the build. But it must be noted that CI/CD was created first and foremost for faster development cycles and code quality maintenance. And, of course, this starts with creating the proper development process – teams who want to integrate CI/CD into their project often start by choosing a branching strategy, choosing the moment when feature branch should be merged with master, choosing how to build and package an application, etc. Development teams practicing continuous integration use different methods to control which features and code are ready for production and they are strictly defined by the process itself.
Most CI/CD tools allow developers to run builds on demand triggered by code commits in the version control system or on a specific schedule. Teams need to discuss a build schedule that works best according to team size, the expected number of daily commits, and other application considerations. The best way to ensure that merges are frequent and build are quick, otherwise, it can slow down team performance.
Main ideas of CI/CD
- The CI/CD process was created primarily to automate the development process
- Automate the process to the maximum, the most time-consuming operations first
- Build on each commit – in this case, it is easy to detect a bug/problem
- Minimize build time – parallel runs of different tests
- Builds are always reproducible – the build is commutative and associative, if the code is not changed, the build remains unchanged
- Infrastructure as code – the entire build process is described in any DSL language (e.g. groovy for Jenkins or yml for Docker files) to match the previous point and always be able to recreate all required artifacts
- Well-coordinated work of developers, testers and DevOps engineers. CI/CD is not possible on the project if the whole team is not working together (as a team).
Testing in CI/CD
Auto-test frameworks help QA engineers identify, run, and automate different types of tests, which can help development teams find out whether a new build is passing tests or not. Automated tests include functional tests that are developed at the end of each sprint and are aggregated into a regression test for the entire application. These regression tests then inform the team if a new code change breaks one or more tests developed in all functional areas of the application where there is test coverage.
Regression tests are just the beginning. Performance testing, API testing, static code analysis, security testing and other forms of testing can also be automated. The idea is that these tests can be run either from the command line, via a webhook, or via a web service and that they respond with status codes.
Once the testing is automated, continuous testing implies that the automation is integrated into the CI/CD pipeline. Some functional and unit tests can be integrated into the CI, which flags before or during the integration process. A test that requires a complete production environment, such as performance and security testing, is often integrated into a CD and performed after the artifacts are delivered to the target environments.
CI/CD supporters claim the benefits of faster time-to-market, faster customer feedback, improved developer productivity, reduced technical risk, improved quality and increased customer satisfaction. I do not question any of these claims. What I do is the cost of switching to CI and CD, the complexity of changing the company's software development culture, and the practical difficulty of maintaining a product that is always shipped. If you are realistic about all this and plan your remediation strategies well, you can benefit from continuous integration and delivery.
There are also large monolithic systems, where without additional modification (for example, large computer systems for banks with releases 3-4 times a year) CI/CD is not suitable, because such tasks require a complete renovation of the entire architecture.
Tools for CI/CD
Jenkins/Hudson, GitLab CI, TeamCity, Circle CI, Bamboo, Microsoft Team Foundation Build, GoCD, AppVeyor, Codeship, Drone
BitBucket Pipelines, Heroku CI, Travis CI, Codeship, Buddy CI, AWS CodeBuild
- CI is essential to create a consistent and automated way to build, package and test applications.
- CD automates the deployment of applications in selected environments
- Regression tests are the basis for CI testing, but besides them, you can automate performance testing, API testing, static code analysis, security testing, etc.
- There are many tools available on the market to create your own CI/CD pipelines.
Daily dose of