PPL2021 — Continous Development — Where Your Development Environment Never Runs Dry
Work smarter…not harder — Allen F. (1930)
When we talk about the development process, it’s easy to forget the importance and significance of git CI/CD. When in fact, pipeline has made developer’s task so much easier. Have you ever wondered what would happen if there is no git pipeline? We must test our code on the server, and then every time we want to merge our work, we have to test it again. After that, when we want to deploy it, we have to configure our server and our repository and do the same step, again and again, every increment. I believe what Allen in above quite, we have to work smarter, not harder. And behold the technology called CI/CD that will ease every developer pain to deploy a product to production.
Introduction to CI/CD
CI/CD stands for two acronyms. The first one is the CI part, which means Continuous Integration. Successful CI means new code changes to an app are regularly built, tested, and merged to a shared repository. It’s a solution to the problem of having too many branches of an app in development at once that might conflict with each other. So, in other words, every time you push your code to the repository, your code will automatically be built (or compiled) and then tested before merging with the existing code in another branch.
The “CD” part in CI/CD stands for Continous Delivery and or Continous Development. Even though these two seems similar, it’s not. Continuous delivery usually means a developer’s changes to an application are automatically bug tested and uploaded to a repository (like GitHub or a container registry), where they can then be deployed to a live production environment by the operations team.
Continuous Development, on the other hand, refers to automatically releasing a developer’s changes from the repository to production, where it is usable by customers. It addresses the problem of overloading operations teams with manual processes that slow down app delivery. It builds on the benefits of continuous delivery by automating the next stage in the pipeline. Usually, Continous Delivery and Development is interchangeable. So for simpleness sake, when I say about CD in this article, it means a process that the developer can enjoy by the end-user. For a better illustration about CI/CD, see the graph below, which pictured as an infinite symbol. It means every step in development is always tied to one another. In other words, you can always have faith that your code will be delivered to the end-user after you have done working on it.
Introduction to Continous Integration
Our project uses the Gitlab pipeline for our CI tools, pylint for the linter, and the sonarqube for the code scanner. We also use three main branches, the lowest branch is called PBI-<backlog description>. On this branch, every developer will write their increment implementation. The middle branch is the staging branch. On this branch, every developer will be merged. On branch staging, we also deployed our work to be tested by our product owner, client, and lecturer. Every code must be built and tested before it can be merged into the staging branch.
We leverage GitLab ability to read YAML file. What is YAML? YAML is a human-readable data-serialization language. In short, GitLab will read the configuration in YAML to execute automatic testing and built.
Because we are using Django (based on python), we don’t have to compile it manually. So we don’t need to say the script to compile it explicitly. See the example below for our CI Script.
So what happens there? In the first part of the code, we tell the pipeline how many stages are there. In this case, we only want the build and unit test part. On the unit test part (test stage), we say what image we use (GitLab uses containers such as docker to contain our code and see my other article for docker explanation). And then, we tell the server what to do with our code. First, we have to download all the requirements from the requirements file. And then did the usual python regime, makemigrations, migration, and then test the code. When the test runs successfully, it will test the code using coverage(python library for testing)
After that, we told our pipeline to connect to the Sonarqube API. Sonarqube is an automatic code analytics tools. It will scan your code about its cleanness, security hotspot, and coverage.
Introduction to Continous Development
Now that the code in every branch has been built and tested. The next step will be combining all that code from various branches to one branch and deploying it to production or staging branches. Just for your information, we use docker latest image and PostgreSQL in Heroku for our database (will be explained in the docker article ). The goal in the CD stage is that our code can be deployed to the server. See the YAML code below before we will break down the part one by one.
So what happens there? Lets’s see the stages part. Now I’ve added the deploy stage. It means the pipeline will deploy our application after the code has been built, tested, and merged. Please pay attention to the deploy-staging part. What happened there is that we explicitly say only execute the script below that part on the deploy stage and ONLY on the staging branch. Then below that is the linter script, which I probably will discuss at a later time in the refactor and the design patter article.
You see that it is the same script. Every time the code is pushed to each branch. It will be built and tested. After it passes that stage, we can merge our work to the staging area, where it will be built, tested, and deployed. It will happen continuously, supporting the infinite symbol where the cycle happens again and again.
Benefits of using CI/CD
- CI/CD will ease your development pain. All you need to know is to write your code.
- One setup will handle everything, the effort spent on the beginning of the project is so much smaller than having to test and deploy every time you made a change.
- Lower maintenance cost because the script only has to be initiated once at the beginning of the project.
- Lower human-error. Using one script will unify every stage and branches. This way, human error regarding testing and deploying will be so much lower and easier to detect.