Release management in the age of SaaS
SaaS products always push the latest and greatest to their users. We have no clue which version of LinkedIn we're on. We just see tiny improvements or complaints about missing "curious emojis".
Behind the scenes, developers merge branches, toggle feature flags, or press buttons to unlock new functionality.
That used to be very different. We used to have packaged releases that contained a new set of features. The next release was a project with fixed scope and a deadline somewhere next year; how the times have changed.
We like to pretend that all of us work in this bleeding-edge SaaS world. That's just not the case. Most of us rely on some kind of gated release.
That's not necessarily because we are "waterfall" or "lack agility". There are plenty of valid reasons why companies can't or won't deploy to production continuously.
Maybe their customers are change avert. I've worked with a few start-ups that catered to Enterprise customers who thought a new version every year was pushing it already. Serving dinosaurs doesn't make you a dinosaur.
They may work in a very regulated environment. If each release requires paperwork and audits, going live every week just isn't in the cards.
They could be building a product that gets hosted by their customers. In that case, teams have little impact on when a new version gets installed.
Building a release management strategy
We'll need a release management strategy if we have a valid reason for gated releases. That doesn't mean heavy-weight processes and go/no-go meetings.
We start by answering this question: Who controls the upgrade schedule?
Can the team decide when to push a new version? Or do they need the green light from their customer? This gives us two types of release strategies: team-driven and customer-driven. Each requires a different approach.
Team-driven release management
When the team decides when a new set of features gets pushed to production, they can go live multiple times a day. They have a business reason to delay go-live, not a technical one.
Too many teams collect new features in a staging environment and then ship a release candidate when they feel it's a valid increment. This has all the downsides of a packaged release and none of the gains. Slow feedback cycles, big error-prone releases, blocked upgrade paths, ...
The better way to handle this is to put new features behind a feature toggle and switch to Continuous Deployment. That gives the team all the tools for a gated release and most benefits of Continuous Deployment. Bugs can be patched straight in production; features can be gated.
While long-lived feature flags still give us late user feedback, regular deploys take away most of the technical risk. We might not have built the right thing, but we don't have to fear crashing the system on go-live day.
Customer-driven release management
Teams that have to get their customer's thumbs up need a different approach. Since they can't control when the new version is installed, they can't rely on feature toggles. They have to depend on packaged releases. Teams in regulated environments often fall into the same category: a deployment with feature toggles might still be a release in the eyes of the regulators.
The way to handle packaged releases in 2023 is through a private Docker container repository and orchestration config (e.g., docker-compose). Clients can upgrade by downloading the latest images.
The main problem to tackle with packaged releases is version support. If a team has ten customers who all get to decide which version they are on, they are likely to support ten different versions of their product. When a vulnerability is found, they'll need to patch it in all of those versions. That's unmaintainable. Let's not even mention the customer support nightmare.
What we need to do here is offer two versions of the product: the Long-Term-Support version and the Lastest version. New features get released by bumping the Latest version; vulnerabilities get patched in both.
Customers who choose the LTS track only need to install a tiny patch. The vulnerability is fixed, but none of the features have changed. Customers who are on the Latest track will need to upgrade to the new Latest version.
After pushing the new version to the container repository, remove the previous image. Don't give your customers a chance to install an older version of your product. This container repo becomes a way to control what your clients can install.
From the team's perspective, they only need to maintain two versions. Since the support of the LTS version expires after, e.g. a year, they also have a mechanism to nudge their change-averse customers towards upgrading. As a rule of thumb, change-averse customers are always risk-averse as well. They won't upgrade for new features, but they will jump to enjoy support.
Both release systems are wildly different, but they give your teams the same benefits:
Simplified version support. Maximum two versions at a time need to be maintained.
Gated feature release with a fast track for bugs and vulnerability patches.
A customer-friendly schedule that's under the control of the team.
The chance to be ahead of schedule. Feature toggles and docker images can be ready long before the official go-live date.
Release Management sounds old-school. Like something you would find after digging up a time capsule. Yet it's a vital component of successful software delivery for those of us who can't deploy continuously.
Are your teams always behind schedule? Would you like to build the habits that make your software delivery reliable yet flexible? Maybe Pair Planning can help.