Version Control – Source Control Branch Design for Deployed Environments

version control

I currently work with a young team of developers using ASP.NET, TeamCity and Octopus Deploy. One of our developers thinks that our system is flawed and introduces the inability to test production hotfixes. What is the best solution to this problem?

We have three environments: development, staging and production. Basically, our workflow only goes forward.

Git push to master -> TeamCity Build -> Octopus Deploy (Dev) -> Promote to Staging -> Promote to Prod

His solution is to have three branches: master (development), staging (staging) and prod (production). We do all active development in our master branch, do any QA in staging and merge from staging to prod when we need to perform a release. When a bug occurs in production, we make the change in staging, and then remerge into production, leaving our development branch alone. We eventually merge all development changes into the production branch once we are ready to release new features.

I don't think this is necessarily right however. My solution is to have the latest production version in the master branch. All development occurs in feature branches. When we've tested a feature branch, we merge back to production. Simple.

So what is the best solution to this problem? Also, some follow-up questions:

  • Should we improve our QA process? Should we be doing QA on feature branches or on full releases?
  • How should we set up our continuous integration? Should we have servers deployed for every version?

I'd love to hear some examples or suggestions you guys may have regarding this scenario. Thanks!

Best Answer

It is good practice to building your code only once and not per environment or branch.

Your GIT branches should not be directly connected to your environment stages.

The pipeline should be as follows:

develop > merge to baseline > build > upload to repo > deploy on dev > test > deploy to Staging > test > approve > deploy to 1 Prod > test > to n Prod.

Always using the same Artifact between promotions. All environments should be mirrors, with environment depend configurations being injected and minimised.

"promotion" is done by the deployment tool and not via GIT branch merging.

I also apply the QA to the full product and not to feature branches.

Testing branches in a vacuum will lead to integration or merging errors not being found and a false sense of security about the quality of the code. It can also create confusion with the Product Owner "I thought it was done and tested ? Why do we get errors now ?"

If you are not applying continuous integration, branching makes sense to split your hotfix from your already developed newer code. As such, simply feed the hotfix into the start pipeline and deploy it over the newest version.

Problems may arise if there are environment or data changes that are not backward compatible between the newest version and the hotfix.

In this case, one normally also includes all the environment and data configurations as a part of the "version" thus rebuilding the full environment every deployment.

This can be easily achieved if the servers are virtual or if they are provisioned via a configuration management tool.

Pratical example: vagrant file for each version. When you rollback from version 1.4.5 to version 0.5.6 you also rollback the vagrant configuration and thus the environment configuration.

While not my initial reference, here is an MSDN Team foundation Server best pratices and patterns: https://msdn.microsoft.com/en-us/library/dn449951.aspx I also advice the reading of the Addison-Wesley signature series books, Continuous Integration and Continuous Delivery