0

I have been researching and am trying to figure out the best branching and deployment strategy to accomplish the requirements below. Maybe I’m missing something but it is more complicated than it seems. Ideally, we’d just have one permanent branch, ‘master’, that could have specific commits tagged to mark releases to production.

Our current strategy is based on Git Flow and has permanent branches ‘master’ (only has releases to production) and ‘develop’. The primary thing that complicates using a multiple permanent-branches model is the concept of “promoting” the same build from the staging environment to production. Currently, this needs to be done in a separate source code branch (deployments to staging come from ‘develop’, deployments to prod come from ‘master’).

Tools: Git (VSTS), TeamCity, Octopus Deploy

Requirements (feature and hotfix lifecycles):

  • All code is reviewed via pull requests (enforced via branch policies)
  • All code gets deployed to a staging environment for testing
  • We can quickly go back to any snapshot of code that was deployed previously
  • If testing is successful, then the same build can be “promoted” from our staging environment to production (no need to build again)

Features accumulate over time before pushing out to production as a single release. Hotfixes have to be able to go through without getting caught up in the "all or nothing" next regular release.

I like the idea of having one permanent branch with tags (re: The master/develop split is redundant, http://endoflineblog.com/gitflow-considered-harmful), but having additional permanent branches may better facilitate deploying to different lifecycles/versions (feature and hotfix) to Octopus.

I have been wrestling with how best to pull this off and I may be over complicating things. Any feedback is appreciated.

FahnzMode
  • 41
  • 1
  • 8
  • What is your question, actually? You've described the infrastructure and some general ideas, but there's no question in your text and no answer could be given (discussion and opinionated comments are not answers indeed). – cyberskunk May 17 '16 at 09:49
  • Sorry about that. I've updated the title. I'm trying to figure out how to accomplish the requirements listed using the tools listed. – FahnzMode May 19 '16 at 16:12
  • This question is too wide. These are 2 automation tools and a SCM, they can accomplish almost anything. Can you offer a design/practice and we see if we can provide ideas to improve it? That might be easier. – Kai Zhao May 19 '16 at 20:10

1 Answers1

1

It seems you have a number of questions and they are quite broad... I'll add some comments to each of your requirements as a conversation starter, but this whole thread might get blocked by moderators as it is definitely not the style of questions SO was made for.


All code is reviewed via pull requests (enforced via branch policies)

I haven't looked at VSTS for ages, but I'd expect they already support branch policies and pull-requests, so not sure if there's anything you need here other than configure settings in your repositories.

In case VSTS does not support that, you might consider moving to a tool that does e.g. BitBucket, GitHub, etc. Both of these have an on-premises version in case you can't (or don't want to) use the cloud hosted version.

All code gets deployed to a staging environment for testing

You achieve that with setting up lifecycles in Octopus Deploy, to make sure deployments/promotions follow the the sequence you want.

We can quickly go back to any snapshot of code that was deployed previously

You already have source control, so all you need now is traceability from the code that is deployed in an environment, to the deployment version in Octopus Deploy, the build job in TeamCity, the branch and exact commit in your source control.

There's a few things that you can do, to achieve that:

  1. Define a versioning scheme that works for you. I like to use semantic versioning. "Major" and "Minor" versions are defined by the developers, and the "Patch" is the auto-incremented number from TeamCity (%build.number%). Every git push build the code and generates a unique build version (%major%.%minor%.%build.number%)

  2. As part of the build steps in TeamCity, before you compile the code, make sure your source files are patched with the version number assigned by each build, the commit hash from your source control, and the branch name. e.g. if you are using .NET, make sure all the AssemblyInfo.cs files are updated with that version, so that the version is embedded in the binaries. This allows anyone to query the version looking at the properties of the binary files, and also allows you to display the app version on the app itself (e.g. status bar, footer, caption, about box, etc.)

  3. Have TeamCity tag your source control with the version number of every build, so you can quickly see on your source control history. You probably only want to do that for the master branch, though which is what you care about.

  4. Have Octopus tag your source control with the deployment version number and the environment name, so that you can quickly see (from your source control) what got deployed where.

Steps 1 and 2 are the most important ones, really. 3 and 4 are just nice-to-have. Most of the time you'll just open the app in the environment, check the commit hash in the "About", and do a git checkout to that commit hash...

If testing is successful, then the same build can be "promoted" from our staging environment to production (no need to build again)

Again, Octopus Deploy lifecycles, and make sure anything different in each environment is defined in the configuration file of the application, which is updated during the Octopus deployment, using environment-specific variables.

In terms of branch workflow, this last requirement makes it mandatory to merge changes into master (or whatever your "production" branch is) before the deployment lifecycle can begin.

C. Augusto Proiete
  • 15,781
  • 2
  • 38
  • 56