Yes, it is possible to accomplish that in Octopus Deploy leveraging lifecycles, channels, and channel version rules.
To solve the scenario in the above question, we will need to create multiple lifecycles.
- FeatureBranch: Development Environment Only
- QA: Testing Environment Only
- Release: Staging -> Production
After the lifecycles have been created then we can move onto the projects. In the project, create three different channels.
Typically we see users add pre-release tags onto their packages. IE OctoFx.2.1.0.1-Development.zip
.
That, in turn, leads to the following rules:
- Packages without pre-release tags can only be deployed to Production.
- Packages with the development pre-release tag can only be deployed to Testing.
- Packages with any other pre-release tag can only be deployed to Dev.
Octopus can help enforce those rules by using a version rule on the channel.
The Design Rule interface will allow you to test out the rule to ensure it meets your specific needs. You can edit/add/remove examples from the sample versions section.
Another nice thing about channels is variables can be bound to them.
Along with steps in the process.
This does mean the build server needs to have a little bit of smarts. When it sees a build come from a specific feature branch it will need to tell Octopus to create the release for a specific channel. At the top of the build a small script will need to be added.
Param(
[string]$currentBranch,
[string]$buildNumber,
[string]$defaultMajorVersion,
[string]$featureBranchVersion
)
Write-Host "BuildNumber: $buildNumber"
Write-Host "DefaultMajorVersion: $defaultMajorVersion"
Write-Host "FeatureBranchVersion: $featureBranchVersion"
$channelName = "Default"
$releaseVersion = "$defaultMajorVersion.$buildNumber"
Write-Host "This is the branch that is building: $currentBranch"
if ($currentBranch -ne "refs/heads/master"){
Write-Host "Non-master branch detected, using feature branches instead"
$channelName = "Feature Branch Channel"
$replacementBranchName = $currentBranch.replace("refs/heads/", "").replace(" ", "")
$releaseVersion = "$featureBranchVersion.$buildNumber-$replacementBranchName"
}
Most build servers allow you to set output variables from script steps.
Azure DevOps/TFS
Write-Host "##vso[task.setvariable variable=octopusChannel;issecret=true]$channelName"
Write-Host "##vso[task.setvariable variable=octopusVersion;issecret=true]$releaseVersion"
TeamCity
"##teamcity[setParameter name='env.octopusChannel' value='$channelName']"
"##teamcity[setParameter name='env.octopusVersion' value='$releaseVersion']"
In the package creation step the version number will need to be supplied from that script.
In the create release step the version number and channel name will need to be supplied from that script.
When manually creating the release in the Octopus UI you would need to select the channel. The channel cannot be change on a release after it has been created.