We run a web development shop with ~20 developers working on ~30 different sites at any given time and we are sinking an incredible amount of time into managing our subversion repositories – there has to be a better way.
Our client sites generally have 3 separate deployment environments: development (trunk), staging (branch), and production (branch).
New features get reviewed internally on development, then merged with staging for client review and approval, and finally merged to production.
Our current workflow: Every developer who is working on a major new feature for a client will create a branch from trunk, work on their feature, while regularly updating from trunk, and then merge the changes back to trunk (development) for internal review. Developers working on minor changes or fixes, will make them directly in the trunk.
After internal sign off, the changes are then merged to staging. If changes need to be made, they will most often be made in trunk, and then merged to staging. Once approved, the changes will be merged with production and then deployed.
New features are not reviewed sequentially internally or by clients, and the whole thing gets rather messy. It seems we are using the wrong processes – there has to be a better way to do this. We are very interested in learning how to utilize version control better, but we are lacking the experience to jump start the process.
What are best practices for these scenarios? In addition to this forum, we are interested in engaging an experienced consultant, who can help us improve our processes.
Thank you!
I think branching by feature (or by team) would be better than branching by developer. The feature can be tested and previewed before merging through Development (Trunk) and into Staging branch.
My team has had a similar “Branch by Quality/Environment” structure that I spent some months researching how to best convert so developers worked together and we could reduce the merge tax. I’d suggest the following:
Staging fixes are made directly in the Staging branch (or short-lived child branch of Staging if QA and/or risk mandate isolation), then merged fix back to Development (Trunk) as soon as fix is accepted. CAUTION: Pay close attention to any merges from Development while a Staging fix is in progress.
From QA Perspective I strongly prefer the final staged-and-tested build be the identical binaries/files released to production. The only change should be configuration files (with different configuration settings checked in to a repository). This means I typically make final build in “Staging” and the “Production” or ReleaseVersion branch is a read-only archive that nobody builds. (A label or tag may be used instead of this safekeeping branch if said lable is immutable… which is not the case for TFS 2010 :-(.)
See the cool diagrams in Visual Studio TFS Branching and Merging Guidance
MSDN article from Feb 2011.
To scale this out see Branching for Scrum and Parallel Feature Teams working on multiple releases in development. Monthly releases to production.. Both of these come with some excellent diagrams that apply to any version control system.
I’d also suggest looking at the TFS Branching Guide and the discussions forum in this same location for additional good patterns and guidance. (Branching methodology is largely independent of tooling with exception when avoiding tool weaknesses.)
I see at least one fundamental flaw in the original branching process:
If a change to Staging is made in Development and then merged to Staging again then you’ve just inherited all other changes made to Development branch since last merge to Staging. OR if you cherry-pick the change (leaving all other changes to be merged later). SCM tools are getting better at handling this scenario, but cherry-pick merges still introduces significant risks.
FYI: The pattern originally described is similar to “Branch By Quality” as described by Jeff Levinson. It can work, but you have to look carefully at how to manage hotfix/qfe branching and merging changes back to Trunk.