The development process can be compared with a construction site. While a lot of work is needed to develop databases, applications, etc., a foundation shall be created to enable productive and reliable software development and delivery. Continuous integration, continuous delivery (CI/CD), and continuous deployment are the foundation practices that make the work on a software product easier.
What does the CI/CD pipeline enable?
We work on complex projects. Therefore, using a continuous integration and continuous delivery pipeline is a common practice in our company. It allows us to automate processes that are repeated and concentrate on things that really need our attention. A properly optimized continuous delivery pipeline brings the following benefits.
It improves code quality
Automated testing and deployment allow increasing the code quality significantly. The code is released in small batches. So, it is possible to test it thoroughly. This approach helps to detect and eliminate the majority of bugs immediately. It, in turn, helps to prevent the accumulation of bugs before the product goes live.
It allows reducing costs and labour thus increasing the development velocity
Automation allows us to reduce the time needed to implement a change to the code or run tests and thus, reduces the costs. It also eliminates the probability of human error. We believe that deployments into the production environment shall be performed without or with the minimum of human intervention, and we optimize the software delivery pipeline to meet this requirement.
It enables us to get fast feedback on any change
The very good thing about the software delivery pipeline is that we can get feedback about a new build immediately. When automated tests detect a bug, we fix it as soon as possible. The same can be told about deployment. If we have implemented a new feature, and metrics tell that the performance dropped, the update is rolled back automatically. So we fix it and release a product that works correctly.
It boosts the customer satisfaction
Our main goal behind the application of a continuous integration and continuous delivery pipeline is to react faster to the required changes. Frequent releases, bugs fixed asap, new features implemented regularly - all these details help us to develop quality software.
Many companies have been applying CI/CD pipeline automation for years. So, the process itself is not new. However, there is always something to improve and adapt to the constantly changing IT environment.
Continuous integration allows us to avoid the so-called “integration hell” when all work done by developers is integrated at the end of a project or by the end of a sprint. Continuous integration allows us to integrate the changes in small parts. So, if there are any issues, they are detected early and can be fixed as soon as possible. It also saves time on regression testing and fixing bugs because they are detected immediately after the changes to code are made. Continuous integration is performed in the following steps.
Test automation: we write automated tests to run them every time a change is implemented to the repository. This approach will enable us to minimize disruptions and detect issues as soon as they arise.
Selecting a CI service: To launch tests every time a new change is introduced, we need a special service or tool that will monitor the changes and push the testing launch. There are many such tools. We can choose one depending on the project’s specifics. For example, we might install a separate CI server, like Jenkins or Bamboo, or we might use the Pipelines feature in a repository if the code is hosted on Bitbucket cloud.
Integrating all team members: while testing automation is required, it is not enough to implement a continuous integration pipeline. So, we have developed the following practices to ensure the continuous integration delivers the wished effect:
- We integrate changes early and frequently - When we make changes to the repository, we integrate them frequently. The reason behind this approach is that if we don’t integrate the code for too long, it might cause a lot of conflicts by merging with the main branch.
- We run simpler tests before more complex ones - We run the simplest tests first to shorten the feedback loop. Further, we move to the tests that run longer. Typically, a testing sequence looks like this: code quality - unit tests - build - staging deployment - end-to-end tests.
We write tests while fixing bugs - It doesn’t matter whether we work with an existing codebase or start a new product, bugs will appear. We always add tests while fixing the bugs. This approach prevents them from reappearing later.
To sum up, implementing continuous integration will require some effort from your team. They will have to write automated tests for every newly developed feature, bug fix, or change. You will need to have a special integration server for the main repository monitoring. This server will also run tests. Finally, you need your team to accept the need to merge their changes frequently.
The benefits you get are evident. Fewer bugs are shipped to production. Building every release becomes easier. The server can run plenty (thousands) of tests per second which makes testing cheap compared to manual testing, and the efficiency of automated testing is much higher. Finally, our QA specialists do not have to spend their time on testing and can focus instead on product improvement that requires human intervention.
Continuous delivery is an extension of continuous integration. It deploys all code changes to a testing or production environment automatically. So, having a continuous delivery pipeline can have a positive impact on your software deployment processes. Instead of suffering from manual deployment, you push a button, and your code is deployed. It enables you to release whenever you need: daily, weekly, monthly, and so on. But the idea of continuous delivery is in releasing as frequently as possible. It enables you to see the issues as soon as they arise and shorten the feedback loop with your users.
To set up a continuous delivery pipeline, we need some prerequisites:
- The continuous integration shall be set up, and the test coverage shall comply with the minimum requirements. If the test coverage is not sufficient, the pipeline will not deliver a wished effect.
- Deployment has to be automated. Once the deployment process starts, the need for human intervention shall be absent. When these requirements are met, you can move on with setting up a continuous delivery pipeline.
While setting up a continuous delivery pipeline is a standard procedure, we have developed some practices to get the most out of it.
Best practices for setting up a continuous delivery pipeline
Here are some practices that we always follow to optimize CD:
- We always have a version control system. When the code is pushed to a repository, the system triggers the pipeline. So, the code pushing to the repo serves as a delivery pipeline trigger point.
- We always analyze the available CD tools and choose those that suit the needs of a specific project.
For example, to set up a CD pipeline for iOS apps, we use Fastlane. It is a tool that has solved all issues connected with mobile apps development. It even generates screenshots, launches Unit/UI tests, connects to Crashlytics, connects to ChangeLog, and in general does many other things that simplify the life of a mobile app developer immensely.
With a continuous delivery pipeline, we deploy software faster and more effortlessly. We don’t spend excessively much time preparing the product for release. And the pressure to make decisions on small changes drops. So, we iterate after and more efficiently.
Without continuous deployment, the pipeline wouldn’t be complete. With continuous deployment, code that has passed all the stages of our production pipeline is released to our customers. The only thing that can stop the release is when at least one test fails.
Continuous deployment allows us to reduce the feedback loop with our customers. It also eliminates the pressure on the team because such a term as “a release day” is eliminated. The code is released automatically when all conditions are met. So, the team can concentrate on developing a product, and the code is tested, released, and deployed automatically when it meets specific requirements.
And again, there are some details to consider if we want our continuous deployment pipeline function as expected.
- First of all, testing: our testing suite is of the highest quality possible. In the end, it determines the quality of our code and product.
It's required that the whole CI/CD pipeline is documented and, although the pipeline requires minimal or no human intervention we still advocate for every member of a team to know how it works.
The benefits of this specific approach are precious:
- We save time and effort on deployment: changes are deployed automatically once requirements are met.
- Deployment is performed in small batches. So, we can see if something needs to be changed asap. It makes the entire process less risky and more productive.
Finally, our customers: they see the work in process, and improvements can be tracked literally daily while earlier, customers could see the implemented changes only on the so-called “release day” (commonly, once per month). So, continuous deployment allows us not only to benefit in terms of time, code quality, team motivation, but also allows our customers to have a continuous stream of feedback from users to account for in business decisions.
There are many ways to reduce time-to-market and cut development costs. Our main goal is by doing so deliver top-notch quality products that scale with the business growth. So, we extensively use CI/CD pipelines to automate the repeated processes but we never use approaches that might lead to the deterioration of our services and product quality.