In many organizations, probably including yours, developers do coding work in isolation in separate code branches. Although this mode of operation deceivingly seems to foster individual productivity of your developers, it makes your team productivity suffer.
Separate code branches make it difficult for you to merge codes from multiple developers. To integrate various different code pieces, make them work in harmony and delivering benefits and features to your clients do usually require involvement of multiple developers, significant reworks, solving conflicts that had to be solved long time ago.
Ironically enough, as merging codes is a challenging and tiring activity within the code building cycles, most development teams unfortunately merge their code before they deliver their application to integration or user acceptance testers, which makes the problem even more impactful. They make successful integration and quality of their joint coding work sole responsibility of quality assurance teams. This is not only ridiculous, but this also perfectly explains why projects delay, project budget deficits skyrocket, team morale and motivation suffer, organizational goals and promises fail, and companies worldwide waste yearly about 600 billion USD for non-budgeted and non-scheduled IT work. Or let’s say IT rework or IT workarounds work…
Your solution for this challenge is trunk (main code branch) based development in combination with continuous integration and test automation. Trunk based development is a source-control branching model, where developers collaborate on code in a single branch called “trunk”. They resist any pressure to create other long-lived development branches.
Trunk-Based Development is your key enabler for Continuous Integration and by extension Continuous Delivery. When your developers commit their changes to the trunk multiple times a day it becomes easy to satisfy the core requirement of Continuous Integration that all of your team members commit to trunk at least once every 24 hours. This ensures your codebase is always releasable on demand and helps to make Continuous Delivery a reality.
Furthermore, frequent check-ins from your developers enable small development and delivery batch sizes which increase quality, make it easier to resolve problems and conflicts. Continuous integration with daily check-ins motivates your team to build deployable, but still meaningful codes in smaller chunks without breaking integrity of your continuous integration & continuous delivery frameworks. Updates in this common source code repository also provides a mean and medium to you and to your team members for quick alignments, decisions and feedback.
Each time a code is checked-in, your continuous integration framework runs automated test cases for the functions and features dependent on, impacted from that changed module. If anything is broken, the owner of this particular check-in is now responsible for fixing the check-in. With top-priority. Nothing else is more important at this moment to ensure that the rest of your team can continue integrating their work to trunk. Until the erroneous check-in will be quickly fixed or rolled-back, no other check-ins to this module of your trunk are allowed to protect the stability and reliability of your trunk.
If you think different from one of these major DevOps principles, the question you need to answer is: Why would you add other new code to a module which already has errors?
You may have legitimate reasons, but let’s make sure that you avoid technical debt and workarounds on the top of workarounds.
Alternatively, your DevOps team can also rely on gated commits which further increase the quality and build another layer of safety net for your trunk.
Each time a developer attempts to check-in a code, test automation runs first to validate the code. Only after successful validation, the code is formally checked-in to your trunk.
One other typical challenge in many IT organizations is inconsistencies between production and pre-production (development, integration and testing) environments. Inconsistencies between your configurations, versions and patch levels of operating systems, databases, third party tools and APIs. Or different versions of your own code scattered all over in various different production and pre-production environments. Even very minor differences in JVM versions between your pre-production and production environments can make or break your entire production deployment. Unless you have the full control of your environments and you know what they have got inside, you can never know what you will get out of them.
Therefore, it is no brainer that your pre-production systems should be the replications of your production systems. You need to enable your team to create self-service environments on demand in automated manner in order to safely do their daily software engineering tasks in production-like environments.
Your IT value stream in your organization does not only offer value with code of your software, but also with environments these codes are running. Both your development and operations specialist need to embrace the fact that, your IT value stream constitutes two equally important building blocks:
With DevOps, tasks to build your pre-production and production environments are now part of your trunk which is the purest definition of Infrastructure as Code (IaC). Instead of your isolated operations teams which hardly know the specifics of software your environments supposed to host, your development and operations specialist work together to build your Infrastructure as Code.
In order to ensure code of your software and code of your environments are treated equally important, you use your single source of truth (trunk) to store the code of your software and as well as your environments.
To be able to build your entire pre-production and production systems and your deployment pipeline including its continuous integration and delivery frameworks, you and your team do not only store code of your software in version control system, but also you store required configurations, scripts and anything required to build your end-to-end delivery chain. If you want to permanently change a configuration setting in an environment you do this change in your environment building scripts, so next time a DevOps team member of yours creates an environment, he or she wouldn’t have to reinvent the wheel.
Most of detailed documentations become anyway very quickly obsolete, so for you it will be obviously a better investment to spend your energy to keep your environment building scripts up-to-date. This is mainly because without having self-service and on-demand environments, your cloud infrastructure will remain yet another underutilized hosting platform and your DevOps initiative will be yet another underutilized process improvement attempt. You should be able to create entire production and pre-production environments from your version control system. With DevOps it is easier and quicker to rebuild environments than fixing them. Manuel changes in your environments are no longer allowed. Only code and configuration should rebuild, configure and launch your environments.
Having your continuous delivery framework and deployment pipeline up and running, now you need a new definition of “Definition of Done (DoD)”.
A task should be now classified as “Done” when its associated client features and benefits are:
With DevOps, integration of your code happens part of your daily work instead of in the end of your projects. Developers, operations teams, information security specialists endless times rehearse deployment of their work already during the course of software engineering lifecycle which undoubtably improves the chance of smooth live deployments.
Higher business throughput, improved software and environment stability, higher job satisfaction, improved quality of service to your internal and external clients will be also your other benefits as soon as you adopt continuous integration.