Search code examples
octopus-deploy

In Octopus Deploy, how to require an approval when a major or minor version is deployed to an environment the first time?


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?


Solution

  • 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. Approval Steps in Deployment 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. Output variable as project variable

    In the manual intervention step, set the run condition to that project variable. Manual Intervention with Run Condition

    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. Current deployment versions

    Success, the manual intervention is skipped. Variable run condition skips steps during deployment

    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.
    Run condition forces manual intervention

    This YouTube Video shows this in action.