Why do we need it?
During the work developers frequently need to update their services and deploy them on the servers. When the amount of projects is small it's not an issue, there are no problems because releases and deployments are rare. Tests are running manually. But when the time comes, a number of services and tasks increases and execution of the same task takes more time.
Let's look at the typical process of feature implementation for the majority of projects:
- Get task from backlog/team lead
- Create a new branch from git
- Implement feature, unit tests to cover new functionality
- Run tests
- Create merge request and wait for code review
- Merge branch to master
- Build an application
- Deploy new build
This process is repeating for EVERY task.
If it takes 10 days for features to be implemented, debugged and tested and 1 hour for building / deploing that seems reasonable and not costly. But if you have a hundred of tiny bugs for one minute each to fix, it seems costly.
The first way is to enlarge merge requests and merge them into the master branch as rare as possible. The second way is to configure CI that process of testing/building/ deploying was running automatically. I do code review every day, this is a big part of my day-to-day activities and I can say that review big code changes is very uncomfortable. So today we will talk about the first option.
Technical goal of the Continuous Integration process is to establish a consistent and automated way to build, package and test applications. With consistency in the integration process in place, teams are more likely to commit code changes more frequently, which leads to better collaboration and software quality.
Continuous Delivery picks up where CI finishes. CD automates application deployment in selected environments. Most teams are working with multiple environments that differs from production, such as development and testing environments, and CD ensures there is an automated way to push code changes to them. They include functionality tests that are developed at the end of every sprint and aggregated into a regression test for the entire application. These regression tests then inform the team whether a code change failed one or more of the tests developed across all functional areas of the application where there is test coverage.
Continuous Integration and Continuous Delivery require continuous testing because their goal is to provide users with quality applications and code. Continuous testing is often implemented as a set of automatic regressions, performance, and other tests that are performed in the CI/CD pipeline.
The mature practice of CI/CD has an option for creating a CD process where all code changes go through CI/CD pipeline and after build deploying straight to needed environments. But you need to understand that CI/CD was created primarily for development. And, of course, it begins with the creation of the development process: teams which want to implement CI/CD on their project often start with choosing branching strategy, with choosing the moment when feature branch should be merged with master, choosing how to build and package application, etc. Development teams practicing continuous integration use different techniques to control what features and code are ready for production.
CI not only packages all the software and database components, but the automation will also execute unit tests and other testing. This testing provides feedback to developers that their code changes didn't break any existing unit tests.
Most CI/CD tools let developers kick off builds on demand, triggered by code commits in the version control repository, or by defined schedule. Teams need to discuss the build schedule that works best for the size of the team, the number of daily commits expected, and other application considerations. A best practice to ensure that commits and builds are fast, otherwise, it may slow down the progress of teams.
Main ideas of CI/CD
- CI/CD process was created primarily for development process automation;
- Automate the process to the maximum, the most time-consuming operations first;
- Build on every commit - in this case, it's easy to identify bug/problem;
- Minimize build time - parallel runs of various tests;
- Builds are always reproducible - build is commutative and associative, if the code does not change, the build remains the same;
- Infrastructure as code - all build process is described in any DSL language (for example, groovy for Jenkins or yml for Docker files) to match the previous point and always be able to re-create artifacts;
- Well, coordinated work of developers, testers and DevOps engineers, CI/CD will be impossible on a project if the whole team is not working together (as a team).
Testing in CI/CD
Automatic testing frameworks help QA engineers to define, run and automate various types of tests, which can help development teams to know, is new build passes tests or not. Automated tests include functionality tests, which are developed at the end of each sprint and aggregated into a regression test for the entire application. These regression tests then inform the team whether the new code change broke one or more tests developed in all functional areas of the application where there is testing coverage.
Regression tests are just the beginning. Performance testing, API testing, static code analysis, security testing and other forms of testing also can be automated. The idea is to be able to run these tests either through the command line, webhook, or in the web service, and that they respond with status codes.
Once testing is automated, continuous testing implies that automation is integrated into the CI/CD pipeline. Some unit and feature tests can be integrated into the CI, which sets flags before or during the integration process. A test that requires a complete delivery environment, such as performance and safety testing, is often integrated into a CD and executed after the assemblies are delivered to the target environments.
Proponents of CI/CD claim benefits of accelerated time to market, faster customer feedback, improved developer productivity, reduced technical risk, improved quality, and improved customer satisfaction. I don't question any of those claims. What I do question are the costs of making the transition to CI and CD, the difficulty of changing the company's software development culture, and the practical difficulty of always maintaining a shippable product. If you're realistic about all of these and plan your remediation strategies well, then you can benefit from continuous integration and delivery.
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 needed to create a consistent and automated way to create, package and test applications
- CD automates application deployment in selected environments
- Regression tests are the basis for CI testing, however, besides them, you can also automate performance testing, API testing, static code analysis, security testing, etc
- There are plenty of tools for creating your own CI/CD pipelines on the market.