Published July 24, 2023
by Doug Klugh

Always Ready for Primetime

Promote continuous delivery by always keeping your software in a releasable state.  Gain high confidence that your software works by integrating changes continuously, while leveraging a deployment pipeline to ensure that your software build is always releasable.  Do not isolate new development within feature branches.  A better way is to integrate those changes earlier by applying them directly on the trunk with a mature suite of tests to protect the build.  Employ DevOps patterns to always keep your software releasable in the midst of constant change.

Release-Ready Patterns

Here are several strategies that can be used to keep your software in a releasable state.

Hide WIP

Maintaining releasable software can be easily achieved amid continuous change by simply hiding the Work in Progress (WIP), such as new feature development, enhancements, or bug fixes.  Feature Toggles enable your team to hide functionality that is incomplete while integrating that half-baked code with the production code on the trunk.  Another method is to simply restrict access to the entry point by holding back specific URIs or UI components.  This will prohibit users from accessing functionality that is not yet ready for release while providing your team the opportunity to test that functionality in production.

meme:  Morpheus - Testing in Production

(I hope) It goes without saying that you should never rely on production-level testing to verify implementation and validate functionality.  All testing in a production environment should always be manual validation with a high degree of awareness that you are testing in production and all transactions, changes, etc. will become part of the production record.  Automated tests should never be run in production due to potential side effects and performance impacts.  Actually, automated tests should never even be deployed to a production environment.  Employ the Test Automation Pyramid in lower environments and treat in-production testing as nothing more than bonus validation.

You can enable testing in your production environment by leveraging Dark Launches, Blue-Green Deployment, Canary Releases, and Ring Deployments.  Restrict access to new functionality to enable your team and select (beta) customers to test in production.  It’s a good way to give a final stamp of approval and establish high confidence that new functionality will work as expected in the actual production environment.

Make Incremental Changes

Take an Agile approach to software delivery by making large changes as a series of small, incremental changes.  Not only will Small Stories make hiding WIP easier, it will also promote frequent feedback, facilitate early error detection, reduce variability in workflow, and increase quality — all of which helps to keep your software in a releasable state.

Branch by Abstraction (BBA)

Although Branching by Abstraction1 is not really branching in the traditional sense, this method does enable your team to isolate new functionality from existing production code.

By encapsulating existing functionality within an abstraction layer (or wrapper), you can build new functionality alongside the old (encapsulated) functionality and create a feature toggle to control which implementation path is used.  Once the new functionality is complete, you can remove the old code, along with the abstraction layer.

The hard part is isolating the entry points to the existing functionality.  Although this should be easy for a well-factored, polylithic architecture, it can be challenging for applications that are more monolithic in nature.

To isolate low-level code, the Strategy Pattern can be used to encapsulate functionality within interchangeable classes while promoting polymorphism.  Or the Facade Pattern can be used to create that high-level abstraction for existing functionality and enable clients to utilize the functionality through an interface of the abstract façade class without knowing which implementation is being used.

1Name coined by Stacy Curl.

Related Posts


assistant Development Tip

Trunk-Based Development

Embrace continuous delivery by frequently integrating small batches of work directly into the source control trunk (at least once daily).  Short-lived branches can be used to implement pull requests or to isolate release candidates, but should never persist longer than a day.  Utilize Feature Toggles to turn off features that are not yet ready for release.  Pull the Andon Cord and fix regression errors immediately to keep the trunk in a healthy and deployable state.

Learn More
assistant Development Tip

Release Candidate

Facilitate continuous delivery by treating every code change as a release candidate.  Each code commit is proven releasable by ensuring it successfully builds, passes all code scans, and passes all its tests — assuming the tests are sufficiently comprehensive and running in an environment that sufficiently resembles production.  Integrate every code commit to ensure the software is always in a working state.  Fix broken builds as quickly as possible to prevent the error from progressing downstream.  Use Feature Toggles to enable product managers and/or business partners to control when a particular feature is released.

Learn More
assistant Development Tip

Feature Toggles

Decouple feature releases from code deployments by encapsulating features and infrastructure changes inside switchable software modules.  Facilitate continuous delivery by deploying code with isolated features that can be released on-demand, enable A/B testing, support operations with automated circuit breakers and kill switches, and provide customized, dynamic feature access to any level of functionality — making Dark Launches, Ring Deployments and Canary Releases a cinch.

Learn More
assistant Development Tip

Dark Launch

Decouple your deployments from your releases by deploying your software to your production environment while disabling/hiding the functionality using Feature Toggles.  Those new features can then be quickly released (turned on) at any time without any additional deployments or downtime.  This is especially useful when employing Trunk-Based Development (TBD) as some features may depend on others that are not yet fully baked.

Learn More
assistant Development Tip

Ring Deployment

Deploy features in a way that facilitates the gradual release to select groups of users in order to manage the risk of software releases.  Start with small groups of low-risk users, then gradually expand the user base to include higher risk users.  This will limit the blast radius in the event of something going wrong and contain the impact to your most loyal customers.  It also provides an opportunity to test new features in a production environment, gather telemetry, gauge user response, and attain customer feedback.

Learn More