12 Factor App — Codebase. Part II

12 Factor App — Codebase. Part II
Reading Time: 4 minutes

by Felipe Quevedo, Senior Software Engineer at Growth Acceleration Partners.

CI/CD Pipeline

In this post, we are digging a little bit on what CI/CD pipeline is and how we can implement it on our project. We aim to achieve our requirement of guaranteeing all the deployments of the application are coming from the same codebase.

While fulfilling requirements is a primary advantage of CI/CD, its benefits extend beyond that. CI/CD enhances the software delivery path by automating necessary processes for deploying changes, ensuring correct functionality and quality. These automations not only reduce the risk of defects, but also decrease delivery time, ultimately boosting team efficiency significantly.

CI/CD stands for Continuous Integration and Continuous Delivery/Deployment. It includes the automation of the processes to get the App changes in production. Therefore, Continuous Integration includes automatic builds, tests and integration of code changes within a shared repository. Continuous Delivery is the extension of Continuous Integration, so it includes automatic deliveries of code changes to production-ready environments for approval and deployment. Finally, we can say we have Continuous Deployment if the deployment-to-production process is automatic.

The CI/CD pipeline could be as simple or as complex as you want. That depends on the decision of the team or the organization. Let’s check the processes that could be involved:

Continuous Integration

This part of the process should include the compilation of the source code with its dependencies. Also, we can have stages like running unit tests and checking code coverage. The goal of this part is to guarantee all the changes of the codebase are in a good position to be part of the codebase, so we can safely merge the changes to the main branch. Thus, we can include all the automations we want to ensure the new code is not going to add bugs in the codebase.

Continuous Delivery

After including changes in our codebase with CI practices, we can extend the automation and include an automatic process for the deployment, configuration management and infrastructure as code in order to have more reliable and consistent releases. The goal here is to have any software version ready to deploy to any environment. That also means new changes and previous versions ready to deploy if we need to rollback new changes.

Continuous Deployment

This practice is about going further with the pipeline, having all the automations to pass the codebase changes directly to the production environment without any check or human intervention. Of course, the changes need to pass successfully all the automated tests.

Now let’s check what a CI/CD pipeline could look like

CI/CD pipeline starts with version control, so let’s extend the example that we started in 12 Factor App — Codebase, where we had a simple workflow for version control. Just to clarify, this is an example of how a CI/CD pipeline could be, and this is not a mandatory pipeline; it could be simpler or more complex depending on what the team decides. Now, let’s focus on the part after Developer 1 creates a pull request.

We can include the first elements of CI/CD when a pull request is done, so this can trigger automatic processes like: compile the source code with its dependencies, run unit tests and check the test coverage of the codebase. This group of processes is called the build.

If any automated process detects a failure in the codebase, the merging will be blocked. Developer 2’s approval of the pull request in the following step does not override this block. Therefore, Developer 1 must address the new code until all automated processes report zero failures on the codebase. This is how CI/CD pipeline is preventing errors on the codebase.

Now that the changes were merged into the main branch, we have a new version of the application, so it is necessary to build the new version. This can be done with an automatic process too, and that could be triggered by the “merging into the main branch” event.

If the build of the main branch is successful, there could be a trigger to deploy the new codebase version to a development environment automatically, so the team can now test the new changes manually. In this case, the team can do integration testing, system testing, user acceptance testing and security testing in the development environment before deployment to production.

In this example, we don’t achieve continuous deployment because the automation process doesn’t extend to its conclusion. Manual testing is performed on the development environment, and deployment to production is contingent upon the team’s decision that everything looks good. If the team approves, they deploy to production using the same build initially used for the development environment. Therefore, the final deployment is not automatic but still easy.

On the other hand, if we want to have continuous deployment, it is recommended to have a robust and comprehensive set of automated tests on the pipeline. Unit tests are not going to be enough, so we also need to automate integration, functional, end-to-end, performance, security and acceptance tests. Remember: this is not mandatory, but since you are deploying to production automatically, you have to be cautious.


By applying CI/CD practices, you guarantee all deployments are coming from the same codebase, which is part of the codebase requirement of the 12 factor methodology. Also, automating stages of the software delivery process allows you to deliver faster updates and features, while maintaining the stability and quality of the overall application. Therefore, teams should be aware of CI/CD practices and decide the processes and tests that could be automated for each project.