About the author
With a tenure of 11 years in the software industry, Bohdan Snisar cultivated extensive experience across a broad range of roles, beginning as a software engineer, progressing to team lead, and software architect.
Introduction
A software release is a critical point in software development: after the release, a software product starts to live its own life, which affects many people in reality. That’s why a release always happens when a fragile balance is reached between the completeness of product features and the necessity to deliver available features to users quickly.
Software releases can remind us of the birth of a well-rounded and healthy baby or the creation of Franskenstein’s monster, and they can say a lot about the development approaches a business takes. In any case, a company can choose varying development principles at various stages. That’s why knowing all these principles can help build the most effective strategy.
Facebook, for example, prioritizes speed in development, which is manifested in one of the company’s iconic conduct rules, coined by Mark Zuckerberg:
“Move fast and break things. Unless you are breaking stuff, you are not moving fast enough.”
This rule, like no other, can demonstrate one of Facebook’s key commitments: to stay ahead in the tech industry, which is known for its extreme competitiveness these days. For that purpose, it needs to come up with new releases quickly.
A Release is Defined by Risks
So releases can show the nature of a business. But what considerations does a company take to determine its approach to releases? It is often heavily influenced by the concept of risk. How do companies measure the risks associated with software releases? There’s a formula, actually:
Risk = the chance that something goes wrong (i.e., the number of changes) * the financial impact of something going wrong
A natural goal of any business is to minimize risks, which are always linked to money loss. There are two major approaches to risk reduction:
- Minimize the number of deployments in order to have fully tested and very stable software updates. This approach is close to a waterfall or cascade development strategy.
- Minimize the number of changes and financial impact for each deployment. This approach centers around the continuing process of delivering small changes, even if they have a minor impact.
Two types of releases: Speed vs. Reliability
These approaches feel conceptually opposite. And they are. While one focuses on reliability, another prioritizes speed. At various points of development, you can decide to use one or another approach. Such a decision usually reflects not only usability but also business needs.
To understand what approach you need to take, you can use the Cynefin Framework, a decision-making model developed by Welsh knowledge management researcher Dave Snowden. He categorized all the problems into five distinct domains: clear, complicated, complex, chaotic, and confusing. Each of them requires a different approach.
- The clear domain is defined by clear cause-and-effect relationships; a speed-oriented approach with standardized processes will work well here.
- The complicated domain requires expertise to determine cause-and-effect. The development strategy must strike a balance between speed and reliability.
- In the complex domain, cause-and-effect relationships can be defined only in retrospect. To learn and adapt, experimental releases are needed here.
- The chaotic domain leaves no chance to figure out cause-and-effect dependencies. A rapid, experimental approach is a must here.
- The confusion domain describes a situation when it is impossible to determine a domain. To start solving a problem, you first need to understand its underlying nature.
Depending on the type of challenges that you face, you can stick to either approach, prioritizing speed or reliability, or find a middle way.
Speed-Focused Software Releases
Frequent and iterative releases of a product are inspired by the “Release early, release often” (RERO) philosophy. It was originally applied to the development of the Linux kernel when the creator of Linux realized that releasing new versions frequently allowed the community to identify and fix bugs faster. The approach focuses on creating a tight feedback loop between developers and testers or users, contrary to a feature-based release strategy. Later, the RERO approach was adopted by some open-source and non-open-source projects.
But faster releases are impossible without changing the management process from top to bottom. It requires delegating responsibility to developers to empower them to deliver changes. The most important component here is trust. Stereamlining fast release delivery is not simple and requires the full involvement of everybody in the process.
The algorithm looks as follows:
- Build something small.
- When it is ready, deploy
- Measure it
- Fix it
- Repeat until Dev, Prod, and Customer are happy.
How can we achieve it? There are a couple of thoughts:
Ownership
To accelerate the pace of releases, a collaborative approach where the lines between development, product management, operations, and quality assurance are blurred is needed. With no development silos, various teams can communicate better and work more cohesively. Every team member becomes involved in the product’s lifecycle, from conception to release, which speeds up development and boosts quality.
Trunk-Based Flow
Trunk-based development revolves around the idea of ‘trunk’, which is a metaphor for a shared main branch. All developers frequently use this branch to integrate their work. This practice helps reduce merge conflicts and promote continuous integration, which leads to faster iterations and deployments.
Feature Toggles
This is a brilliant invention that helps control the flow of code execution. Feature toggles enable hiding features, which are developed and integrated right into the main codebase. This enables you to deploy any changes to production and open them to a selected group of users for testing in a live environment. Feature toggles help easily roll back problematic features and mitigate risks associated with the deployment of unfinished features.
Reliability-Oriented Approach to Releases
However, the principles I listed above are not universal. They align with the ideas of the Agile manifesto, which says “business people and developers must work together daily throughout the project.” However, such a philosophy can be interpreted as a legalization of chaos throughout the development cycle. This can be detrimental for projects of a larger scale, say, the construction of a spacecraft. In this context, control makes a lot of sense, doesn’t it?
Larger and more complex product development cycles may be incompatible with fast-paced software releases. They may need rigorous and time-consuming manual testing, including unit tests, integration tests, and end-to-end tests. That is where a fixed release schedule may appear, which can help properly allocate resources. Moreover, such an approach can require the use of a staging environment that mirrors production.
GitFlow
Large projects require more time and reliability, and errors in large systems can lead to unexpected consequences. To make managing large projects easier, the branching model GitFlow was created. It standardizes the process of feature development, releases, and bug fixes.
The workflow in this case consists of a number of branches, including the master branch, develop branches, release branches, and hotfix branches, all of which have clearly defined functionality. GitFlow structures workflow, isolating the work on separate features, which, in the long term, can reduce the number of errors.
However, GitFlow is often criticized for its complexities, which make it difficult to use in today’s development environments that prioritize speed. The model’s complex structure, which includes five branches, may create an excessive cognitive load on developers and lead to an increasing number of merge conflicts.
GitFlow is hardly compatible with modern-day approaches and technologies that dominate the development mainstream globally. For example, it makes continuous delivery difficult because of its long-term release cycle. GitFlow is also impractical for both microservice architectures and monorepos.
While Git Flow might suit large teams with infrequent releases, it can be hard to use by smaller teams working on smaller-scale projects.
Conclusion
Summing up, I can say that business objectives should guide the choice between speed and reliability in software releases. It is always a compromise, which can include the use of varied tools and methodologies. And knowing what tools will work better at a particular moment of the development cycle can help businesses remain effective and productive!
