Imagine you had five environments, Dev, Test, UAT, Stage and Production.
For those environments you have the following lifecycles: - Sprint: Dev -> Test - Test To Prod: Test -> UAT -> Stage -> Prod - UAT to Prod: UAT -> Stage -> Prod - Hotfix: Stage -> Prod
The release versioning looks like 2020.1.3. When a new release is cut it will either update the major (2020) or minor (1) in the version number. For example 2020.1.3 goes to 2020.2.1 or 2021.1.1. A bug fix or minor release will update the last number (3).
The concern is if a release is deployed to Test, UAT or Stage at the wrong time or by accident and it stops our testers. For example, QA is in the middle of testing the 2020.1.3 release in Test. A developer accidentally pushes 2020.2 up to Test. That includes new code QA wasn't expecting. While QA is in the middle of testing 2020.1.x they only want to see 2020.1.x releases.
We don't want to use version rules in our channels. Each time a new release is cut the version rules would have to be updated.
Is it possible to require an approval when a major or minor version is deploy to an environment the first time?
Yes, that is possible. To do this, we will use output variables and run conditions.
First, two new steps were added to the start of the process.
Both steps skip development and production because they are not affected by this problem. Having to approve a deployment to dev every time a major/minor version changes will get old really fast. And all production releases must at least go to staging first.
The first step runs this PowerShell script. It will compare the previous release number for this specific environment with the current release number. It will set the output variable "RequiresApproval" to true if either the major or minor version is different.
$releaseNumber = $OctopusParameters["Octopus.Release.Number"]
$releaseNumberArray = $releaseNumber.Split('.')
$lastVersion = $OctopusParameters["Octopus.Release.PreviousForEnvironment.Number"]
$lastVersionArray = $lastVersion.Split('.')
Write-Highlight "The previous version deployed to this environment was $lastVersion"
$requiresApproval = $false
if ($lastVersionArray[0] -ne $releaseNumberArray[0])
{
Write-Highlight "The previous major version $($lastVersionArray[0]) in $lastVersion is different than the one being deployed $($releaseNumberArray[0]) in $releaseNumber, this requires someone to approve"
$requiresApproval = $true
}
elseif ($lastVersionArray[1] -ne $releaseNumberArray[1])
{
Write-Highlight "The previous minor version $($lastVersionArray[1]) in $lastVersion is different than the one being deployed $($releaseNumberArray[1]) in $releaseNumber, this requires someone to approve"
$requiresApproval = $true
}
else
{
Write-Highlight "The previous version's major and minor versions are the same, skipping approval"
}
Set-OctopusVariable -name "RequiresApproval" -value $requiresApproval
Output variables are a little verbose and can be tricky to use. To make that easier, create a project variable to reference it.
In the manual intervention step, set the run condition to that project variable.
Now it is time to test this. UAT currently has 2020.1.2
while Test has 2020.2.3
. When 2020.2.4
is deployed to to Test the manual intervention shouldn't appear.
Success, the manual intervention is skipped.
UAT currently has 2020.1.2
. 2020.2.4
has a new minor version, a deployment to UAT will prompt the user for a manual intervention.
This YouTube Video shows this in action.