Continuous integration (CI), continuous deployment (CD), and continuous testing (CT) are key practices in the DevOps philosophy. CI involves merging code changes from developers into a shared repository, building and testing the code automatically, and alerting the team of any issues. CD is about automating the process of releasing code changes to production environments. CT involves continuously running tests to ensure the quality and functionality of the code. By implementing CI, CD, and CT, organizations can improve the efficiency and speed of their software development and delivery process, ultimately leading to faster time-to-market and more reliable software releases.
In this tutorial, we will learn about the benefits and go into some practical work on building a CI, CD, and CT pipeline with GitHub Actions.
Here is what you need to get started and follow along.
GitHub and Docker hub accounts
Basic knowledge of GitHub
Introduction to CI
Continuous integration (CI) is a software development practice for automatically merging code updates into a common repository typically stored in a version control system. This practice is commonly used in agile software development, where teams work in short, iterative cycles to quickly deliver new features and updates.
Continuous integration aims to reduce the amount of time and effort required to integrate code changes and ensure that the software is always in a stable and working state. This is achieved through several practices, including:
Local testing: This involves running tests locally on the code after each change is made, to ensure catching any bugs or regressions early in the cycle.
Code review: This includes a code review process, where other team members review the code changes before they are merged into the main repository. This can help identify issues around the code as well as product quality.
CI with GitHub Actions
Here, we will use GitHub Actions to demonstrate CI, however, the steps are similar regardless of the tool we use. We will work with an existing Python code with unit tests.
GitHub Actions is a powerful tool equipped with continuous feedback that allows us to automate our software development workflow, including building a CI/CD/CT pipeline for Python code. The pipeline we will create now will check out the code, set up Python, and install dependencies that’ll run the application.
To get started, we will create a new file called main.yaml at the path .github/workflows/ main.yaml. This is where we will define our workflow, which is the pipeline configuration. In the main.yaml file, we can define our workflow using the syntax of the GitHub Actions workflow language. Let us paste the following configuration into the file we just created.
We are using a project on GitHub, so you can clone it and follow along.
name: CI/CD/CT on: [push] #specifies the event that should trigger the workflow (e.g., on: push). jobs: # specify the specific jobs that should be run as part of the workflow build: runs-on: ubuntu-latest steps: # For each job, you can specify the steps that should be run - uses: actions/checkout@v2 - name: Set up Python 3.8 uses: actions/setup-python@v2 with: python-version: 3.8 - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt
This workflow defines a single job called "build", which is triggered whenever code is pushed to the repository. The job consists of several steps:
The actions/checkout@v2 action checks out the code from the repository.
The actions/setup-python@v2 action sets up Python 3.8 on the virtual machine that will run the job.
The Install dependencies step installs the dependencies specified in the requirements.txt file using pip.
Now any code can be pushed into this repo and the rest of the processes will be handled by GitHub. Push your code to GitHub and go to your project on GitHub and click on the “Actions” tab, you will see that the build was successful.
Introduction to CT
Continuous testing (CT) is a software development practice in which automated tests are run regularly to ensure that the software is functioning as expected. This practice is often used in conjunction with continuous integration (CI) and continuous deployment (CD), where code changes are regularly merged into a shared repository, automatically built and tested, and then deployed to a production environment.
The goal of continuous testing is to identify and fix issues with the software as quickly as possible, and to ensure that the software is always of high quality. This is achieved through many practices, including:
Automated testing: Continuous testing typically involves running a suite of automated tests on the code, to ensure that it is functioning as expected and to identify any potential issues or bugs
Test coverage: Continuous testing also typically involves ensuring that the automated tests cover a wide range of scenarios and conditions, to ensure that the software is thoroughly tested and any potential issues are identified
Continuous feedback: Continuous testing often includes mechanisms for providing feedback to the development team, such as notifications of failed tests or alerts when code changes introduce new issues.
CT with GitHub Actions
We will continue to build on top of the example that we started in the CI section. We will include a step that will run Python tests on the application. This will serve as the CT in our pipeline, though, there can be other tests that could be put here, like linting tests.
To get this done, let us add the following code to the job created earlier and push your code to GitHub. We can check the “Actions” tab on GitHub to review the status of our executed tests.
… - name: Run tests run: | Pytest
Introduction to CD
Continuous deployment is a software development practice in which code changes are automatically deployed to production without the need for manual intervention. It is a more advanced form of continuous delivery, where code changes are automatically released to users as soon as they pass the build and test process. Continuous deployment helps teams ship software faster and more frequently, by eliminating the need for manual approvals or manual steps in the release process. It requires a high level of automation and testing, as well as a robust infrastructure for deploying code changes. Continuous deployment can help teams iterate quickly and deliver value to their users more frequently, but it also requires a high level of discipline and attention to quality.
CD with GitHub Actions
Let us add a new step that will build a docker image for your application and then deploy it to Docker Hub. Our code will only be deployed to Docker Hub if the tests pass.
… - name: Build Docker image run: | docker build -t Docker_Hub_username/name_of_image:v1 . # replace with the appropriate info - name: Push Docker image to registry run: | docker login -u Docker_Hub_username -p passwordxxx #replace with your docker hub credentials docker push Docker_Hub_username/name_of_image:v1
The Build Docker image step builds a Docker image of the code. And the Push Docker image to registry step pushes the Docker image to Docker Hub.
How CI, CT, and CD Work Together
Together, CI, CT, and CD form a powerful toolset for managing the software development process and ensuring that code is of high quality and can be quickly and reliably released. CI, CT, and CD are stages of an automated system.
CI, by integrating code changes from multiple contributors into a single codebase frequently, helps to identify and fix conflicts and other issues quickly. This reduces the risk of errors and ensures that the codebase remains stable and consistent. Platforms like GitHub are essential for this to work. When the code is pushed to GitHub, the other processes in the pipeline(CT/CD) will be triggered.
CT, by running automated tests on the codebase continuously, helps to ensure that the code remains working. This can catch issues that might otherwise go unnoticed and helps to prevent bugs and other problems from being introduced into the codebase. Here, the tests are run against the code to check for failure, if there is a failure, the code will not move to the next stage of the process (CD).
CD, by automatically deploying code changes to production environments as they are made, allows for quick and reliable releases. This reduces the time and effort required to release new features and updates and helps to ensure that the code is always up-to-date and available to users.
They are an essential part of modern software development and are widely used by companies and organizations of all sizes.
Benefits of a CI/CD/CT Pipeline
Faster software delivery: CI/CD/CT pipelines allow developers to quickly and automatically build, test, and deploy their code, reducing the time it takes to get new features and fixes to users.
Improved software quality: By automating the testing process, CI/CD/CT pipelines can help ensure that code is thoroughly tested and meets quality standards before it is deployed.
Reduced risk of errors: By automating the deployment process, CI/CD/CT pipelines reduce the risk of human error, such as mistakes made while manually deploying code.
Enhanced collaboration: CI/CD/CT pipelines can facilitate collaboration among developers by allowing them to easily merge their code changes and automatically test and deploy them.
Increased efficiency: CI/CD/CT pipelines can improve the efficiency of the software development process by automating repetitive tasks and enabling developers to focus on more important tasks.
Improved security: CI/CD/CT pipelines can help improve the security of software applications by automating the testing and deployment of security patches and other updates.
In conclusion, CI, CD, and CT are important concepts in DevOps that help organizations deliver high-quality software, faster and in a more reliable way. By implementing these practices, organizations can improve the efficiency and effectiveness of their development and deployment process, leading to better user outcomes.
We looked at GitHub actions, but there are many CI/CD platforms like Tekton or Circle CI that are very popular across different teams. Since this was just a basic introduction, our next steps could be to improve the pipeline by adding something like linting or deployment.