Restrict deployment to certain environments based on version tag

I’m finalising my CI setup with TFS and I have one last part to overcome. Currently, every CI build is pushed to octopus with the nuget packages versioned as major.minor.patch.buildid, and these are used in releases in Octopus versioned as major.minor.patch-beta{buildid}. Therefore, every CI build will be tagged as a beta build for a given release, e.g. / 1.3.0-beta194. There will no doubt be a number of iterative dev builds before one is chosen to go to the test team - let’s assume the chosen build is 194 in this case. At this point I envisage the creation of a new build, 1.3.0-rc1, which uses the build 194 binaries. This is then pushed to the test environment and testing begins. There may be a number of testing cycles, so let’s say the testers sign off the version 1.3.0-rc4. A new release could then be made, 1.3.0, based on the 1.3.0-rc4 binaries, which is the gold release for the product.

Firstly, is this a good idea? Some feedback would be much appreciated.

Seperately, is it possible to restrict deployments to certain environments based on a tag in the version? In my example, I would never want a release marked as -beta to be deployed to a test environment - only -rc builds should be. Likewise, only tag-less builds should be deployed to production environments.

Hi James,

Thanks for getting in touch!

The answer to your second question is fairly easy: yes, you can restrict deployments to certain environments using Channels. Take a look at the Channels Walkthrough: Safer standard release promotion where we describe this configuration in detail.

The answer to your first question is a bit more detailed. We generally recommend build your binaries once, but for Octopus Deploy itself we use git-flow where we will end up building the same revision/commit again to promote a release. The main reason for this is because we have a similar internal-test and early-access program, and we use GitVersion to bring structure and determinism to our assembly versioning. This is based on git branches and tags, and that version number is stamped into our assemblies. If we repackaged the 3.3.0-beta.2 assemblies into a 3.3.0 package, we’d have a mismatch and create confusion, so we rebuild the same commit. This process is also more convenient since it’s the exact same build process, and we are willing to take on the slight risk that building again from the same commit may not have the exact same result. You could also argue that repackaging may have some unintended side-effects…

In your situation, it doesn’t look like you’re stamping your assemblies with a Semantic Version, so you could potentially repackage the same contents as a new release/version, and the end-user wouldn’t know the difference.

In the end it will really come down to balancing the complexity of your process with the level of rigour you want to apply to ensuring the tested version matches the released version. Personally I’ve become very comfortable using the git-flow approach.

Hope that helps!

Hi Mike

Thanks for the reply, there is loads of good stuff in there! You’re right that we aren’t stamping our assemblies/packages with a SemVer tag, they contain only a version number and a build number (e.g. This means that only the Octopus release is decorated with SemVer tags, e.g. -beta. From my preliminary work, it appears that Octopus channels only look at tags on packages, rather than tags on releases; this means that I couldn’t stop a release tagged as 1.3.0-beta194, containing binaries of version, from being promoted beyond a beta environment. Is this right?

Hi James,

Thanks for getting back to me. You’re right, with Channels we add safety by using Version Rules, which restrict the packages that can be used to create a release in a Channel.

In your situation, you won’t get any benefit from Version Rules, meaning you will need to be careful which Channel you select when creating a Release. But, you can still benefit from Channels - you could just create the Release(s) selecting the desired Channel. Once a Release is in a Channel, it will stay in that Channel, unless you change it manually.

So in this case you could:

  1. Create the 1.3.0-beta0001 etc release in the Dev Channel with the packages, and once happy that .194 is to be promoted
  2. Create the 1.3.0-rc0001 etc release in the Test Channel using the packages. And once happy…
  3. Create the 1.3.0 release in the Main Channel using the packages.

This just means that someone has to be responsible for creating those releases with the right packages in the correct channels.

Personally, my preference would be to investigate and consider using SemVer and getting the automation and safety benefits Channels with Version Rules has to offer.

Hope that helps!

That all seems to make sense. We are using TFVC rather than Git, so I don’t think it is possible to adopt git-flow (please correct me if I’m wrong!). Once our binaries are pushed in to Octopus, we don’t rebuild them, so perhaps I should move to SemVer versioning with a build number suffix for releases, in the same way as we do for binaries (e.g.

Unless you can suggest a better option?

Hi James,

Thanks for getting back to me. At this point I think that plan is worth testing and seeing how it works for you and your team, and then re-evaluate and adjust.

Hope that helps!