We have three environments: Dev
, UAT
and Prod
. We use TFS
to schedule releases of our master
branch into Dev
for our internal verification, then UAT
for business verification, and of course finally to Prod
once approved.
We've recently adopted a new lightweight Git branching strategy as follows:
master
is always prod-ready. At any point master
should be able to be deployed to production.
All new development is done in a separate feature (topic) branch as follows:
- Create a new feature branch off
master
, call itFeatureA
- Develop
FeatureA
until completion - Once
FeatureA
is finished, release it toDev
, and thenUAT
- Once the business signs off on
FeatureA
inUAT
, it's considered prod-ready. MergeFeatureA
intomaster
, then deploy the newmaster
branch toDev
thenUAT
. During the way, "smoke test" the branch inUAT
to ensure the resulting merge into master didn't cause any unforeseen side-effects. Once smoke-tested, release toProd
.
The problem we're coming across right now is that we may have multiple features being developed in parallel, all of which could potentially need to be deployed to the test environment for verification at the same time. The approach we've taken to solving this problem is:
If FeatureA
and FeatureB
need to be in UAT at the same time, then:
- Create a new branch,
FeatureAandB
, which will encompass both features - Merge
FeatureA
intoFeatureAandB
- Merge
FeatureB
intoFeatureAandB
- Release
FeatureAandB
toDev
, thenUAT
The downside to this is that it's unlikely both FeatureA
and FeatureB
will be UAT
verified at the same time. If FeatureA
is verified and FeatureB
is not, we need to release FeatureA
to prod without FeatureB
. What we've discussed in this scenario is to:
- Merge
FeatureA
(not the joint branch, but just FeatureA) intomaster
- Release
master
toDev
, thenUAT
for a quick smoke-test, and finallyProd
- Once in prod, re-release just
FeatureB
toDev
thenUAT
so testing can continue.
The downside to this is that it directly impacts any testing for FeatureB
, and potentially unwinds any work the testers have accomplished with FeatureB
.
How do you manage multiple features living simultaneously in each environment and being released potentially independent of one another? We can mitigate the issue a little more if we have multiple environments, or turn-around UAT testing much quicker, but at the end of the day the same problem can exist.
I'm not opposed to hearing alternative branching strategies, either.
Best Answer
Ahh. Congratulations! You’ve destroyed one bottleneck and discovered the next one! Now it’s time to look at actually continuously integrating your code. As you’ve found out, it’s hard to continuously deliver when your code under dev isn’t being continuously integrated, but how do you make this work?
No more feature branches.
No. Seriously. No more feature branches.
It’s time to introduce feature toggles into your system. Instead of delivering new features by delivering code, you need to have complete control over when a feature is turned on for a given environment. In other words, you want to have environment specific configuration that turns features on and off. This decouples code releases from feature releases.