Software Deployment, Environment, and CI/CD


This is written to fulfil individual review criteria for PPL Fasilkom UI 2021.

Hi guys, it’s me again! In this article, I will be discussing software deployment, software development environment, and CI/CD for automated deployment. Are you interested in learning them? Read more to find out :)

All of the tasks that go into making a software system usable are referred to as software deployment. It involves all of the steps, procedures, and activities required to make software available to its intended users. When developing software, there’s this term called “localhost”, a local server that can serve the being developed software so developers can test their work there. However, if we want to make our software available to other people, we can’t use localhost. Therefore, we need to deploy our software.

When we create small-scale applications, only having one environment (production) is usually not a problem. For instance, PPW group assignment (well, yes, at that time, we didn’t know anything about software environment). But try to imagine if we have to make large-scale applications. For example, assume that we have just been accepted to work as a software engineer in a large company where the application users have touched the millions (amen). Then, we, as new software engineers, are asked to update a specific feature. Imagine if there is no software environment, that means our code will immediately be deployed to production where the actual users can directly access the changes. Suppose we accidentally make a bug in our code. In that case, that is very dangerous because even though the bugs may be minor, in an instant, millions of users could all know the application bugs. We will make the company reputation bad because of low-quality software. But that’s still a good case example, though. Imagine if our changes make the software break to the point that no one can access it. That’s the worst nightmare ever. In other words, applications in production (which can be directly accessed by the user) should be bug-free as much as possible. So, what about the best practice for implementing this? The answer is to create a software development environment.

In short, a software development environment is a practice where developers use environments to create “stages” as they progress through the development process. The primary purpose of making these stages is to prevent customers see the messy side of the application, like what I’ve mentioned earlier.

The environment stages that are very commonly used in software development are as follows (it can be different for different teams):

  • Development
    This environment is where all code changes are made. So this is where the majority of the work of developers is done. It’s typically set up on local computers, and the work is usually facilitated by a version control system such as a Git repository. Users and customers will be unable to access anything done in this environment unless we demonstrate it to them. This environment is just for developers to see and test how new features will work, so it won’t affect anything real users see from the original software. This stage usually uses a local database/dummy database not to affect the actual database. Therefore, we have to ensure that our code works here and does some fixing if necessary before releasing it to the following environment.
  • Staging
    This stage is similar to the production environment. We will have a server that can serve our application here instead of our local computer. But still, this won’t affect the production environment. In this stage, we can test our application as a whole, do database migrations. If we have clients, we can also use the deployed application of this stage for demo purposes. Clients can see how the application will be when it’s live, and the developers can immediately get feedback. We have to think that this is our last chance to check everything out and fix bugs (if any).
  • Production
    Production is where we can make our application live. When it enters the production stage, that means the software is finally accessible to intended users. It’s safe to say that this stage is the most critical because this is the final destination of our application. This is our primary goal as developers, which is to make the application accessible to users. As I’ve mentioned earlier, this stage should be bug-free as much as possible. Maybe it sounds scary at first. Now that we know that we must have been testing the application at the previous stages, we also know that it’s possible to do so.

Now we know that we have to deploy, be it for a production environment or a staging environment. But, how is the deployment mechanism? Do we have to wait a long time (hours, or maybe days) after we finish doing something before go into the next step? Certainly not. It will be very time-consuming. To save time and make work more effective, we can use CI/CD for automated deployment.

CI in CI/CD stands for continuous integration. It makes sure all of the developers’ code is merged in one place. An example of implementing CI is by using Git. It makes it a lot easier for developers to integrate their code in one place and update one’s code with the updated one, even if it’s from other developers.

CD in CI/CD can stand for continuous delivery/continuous deployment. They are related concepts that it’s often used interchangeably.

Continuous delivery makes sure that our code is continuously ready “to be shipped”. It involves automation of the entire software release process, such as build and test.

Continuous deployment, just like its name, can refer to automatically deploying developers’ changes from the repository to production/staging, depends on its desired environment.

All of them can be automated by building a script for CI/CD pipeline. Further details will be explained.

Here is an example of CI/CD implementation In PPL 2021.

We use Gitlab to store our code as well as our CI. For the development environment, we use our local computer and keep the code in the PBI branch. We use the staging and master branches for staging and production environments, respectively. After writing our code in development, we have to test our code first and see if it works before bringing them up into the staging branch. For production, as I’ve mentioned earlier in the Git article, only the Product Owner has the right to merge from staging to master.

The flow is when we push whatever changes to a branch, it will automatically run the CI/CD script, which is .gitlab-ci.yml.

For CD, there are 3 stages that my team use, such as test, sonar-scanner, and deploy.

The test stage is where we build and test our application. The sonar-scanner stage is where we scan our application using sonarqube to detect any software quality issues. The deploy stage is where we deploy our application. For now, it’s only available for the staging environment.

Gitlab CI/CD will run the CI/CD script sequentially, based on the stages (testsonar-scannerdeploy). Therefore, if we fail on a particular stage, it will automatically stop and skip all the remaining stages. For example:

It passed the test stage, but failed in sonar-scanner stage. Accordingly, it will stop and skip the deploy stage.

This is the example of passing all of the stages:

For our CI/CD script, please refer to this link.

By default, the CI/CD will work for all branches. But, for some purposes, we need to restrict some stages to some branches only. For example, for deploy stages, it’s only applicable for staging branch for now. So, we can restrict by adding these lines:

After adding those lines, all changes in branches that are not staging won’t run the deploy stage. For example:

There are just 2 stages there, test and sonar-scanner.

We can also exclude some changes so the stage won’t run. For example, we want to exclude changes in the deploy stage. Just add the following lines:

Now, if we look at our CI/CD script which is .gitlab-ci.yml, there are some variables whose values have to be set. The variables are marked with $ prefix. For example: $HEROKU_APIKEY, $SONARQUBE_TOKEN, etc. For making CI/CD run perfectly, we have to set those variables in Settings > CI/CD > Variables.

For instance:

The purpose of doing this is to secure our application from unwanted actions. Credential variables must not be exposed in the source code. The variables are not only restricted to what I’ve mentioned above. It depends on each project’s needs.

CI/CD really makes developers’ work effective and efficient by automating many tasks so that developers can be more focused on their work.

To sum up, best practices when releasing software are as follows:

  • Create a software development environment as we progress through the development process
  • Implement CI/CD, especially for automated deployment to make everything efficient & effective

Okay that’s all for now! I hope you gain new insights about deployment, software development environment, and CI/CD from here! Hope it enlightens you :D

Have a nice day!

Glenda Emanuella Sutanto
PPL-D 2021

an aspiring software engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store