Firstly, it’s important to understand that we don’t generally recommend deploying projects partially. The reason for this is fairly simple; it becomes very difficult to know exactly what has been deployed from both the dashboard overview or project dashboard.
However, with that being said we appreciate that there are situations where you may want to do this.
There are a couple of options in Octopus you can leverage to help deploy using the all-or-some approach.
Solution 1 - Excluded steps deployment option
This solution makes use of the built-in Excluded steps option in the deployment screen:
Here you can use the checkboxes to select steps to exclude from the deployment.
For a major release, you wouldn’t need to select any of the steps to be excluded. For a patch or minor release, you can select all of the steps you don’t wish to deploy.
This is by far the simplest option and allows for granular control for user’s wishing to exclude steps in a deployment. For this reason, it’s the recommended approach for simple cases.
Solution 2 - Prompted variables, output variables and variable run conditions
The alternative option is to make use of:
In this example, we will make use of a run a script step a that determines whether a complete or partial deployment is required. This step will set output variables that can then be used in run conditions in the subsequent deployment steps.
Prompted variables will be used in the Production environment to allow the user the ability to control whether or not Application A or Application B’s steps should be deployed.
This approach has the benefit of being able to be more selective in which steps run in your deployment process for either a major or patch version being deployed. The downside of this approach is that your deployment process arguably becomes more complex and intricate. You should consider these pros and cons when you decide if it’s appropriate for your situation.
For the purposes of this solution:
- A major version will be considered a SemVer major increment, e.g. from
2.0.0.0
to 3.0.0.0
.
- Anything else will be considered a patch (or minor) version, e.g. from
1.0.4.0
to 1.0.5.0
In our example deployment process we’ll have the following steps that should only be deployed on a major version deployment:
In addition, steps 4 - 7 highlighted below will be deployed only either on a major or a patch version deployment:
The reason for having the steps above run on both a major or a patch version deployment is to facilitate both a complete and a partial deployment of the project.
Check deployment version - script step
Firstly we need to create a script step which works out which version is being deployed. It contains the following PowerShell code:
$ReleaseNumberBeingDeployed = $OctopusParameters['Octopus.Release.Number']
$ReleaseNumberAlreadyDeployedInEnvironment = $OctopusParameters['Octopus.Release.CurrentForEnvironment.Number']
$newerMajorVersion = $false
$patchVersion = $false
if([string]::IsNullOrWhitespace($ReleaseNumberAlreadyDeployedInEnvironment))
{
Write-Host "First deployment to environment. Newer Major version automatically set to true..."
$newerMajorVersion = $true
$patchVersion = $false
}
else {
# Handle any pre-release tags
$idx = $ReleaseNumberBeingDeployed.IndexOf("-")
if($idx -ge 0)
{
$ReleaseNumberBeingDeployed = $ReleaseNumberBeingDeployed.Substring(0, $idx)
}
$currentReleaseVersion = New-Object System.Version($ReleaseNumberBeingDeployed)
$idx = $ReleaseNumberAlreadyDeployedInEnvironment.IndexOf("-")
if($idx -ge 0)
{
$ReleaseNumberAlreadyDeployedInEnvironment = $ReleaseNumberAlreadyDeployedInEnvironment.Substring(0, $idx)
}
$envReleaseVersion = New-Object System.Version($ReleaseNumberAlreadyDeployedInEnvironment)
if($currentReleaseVersion.Major -gt $envReleaseVersion.Major)
{
Write-Host "Newer major version is being deployed: $currentReleaseVersion"
$newerMajorVersion = $true
}
else {
Write-Host "Major version is not higher, assuming minor / patch is being deployed"
$patchVersion = $true
}
}
# In this example, we want to deploy an application if:
# - A newer Major version is being deployed, or
# - A patch version is being deployed
$shouldDeployApps = ($newerMajorVersion -or $patchVersion)
Set-OctopusVariable -name "NewerMajorVersion" -value $newerMajorVersion
Set-OctopusVariable -name "PatchVersion" -value $patchVersion
Set-OctopusVariable -name "ShouldDeployApps" -value $shouldDeployApps
The script step above is written in PowerShell but can be converted to a language of your choice. It simply compares two versions with one another:
Octopus.Release.Number
- this is the version of the project release version being deployed
Octopus.Release.CurrentForEnvironment.Number
- this is the project release version of the project that is already deployed to the Environment.
By comparing these two Octopus system variables, we can make a decision as to whether the version about to be deployed is higher than the version currently deployed to that same environment. This allows us to qualify is this deployment is a major or a patch version deployment.
We then set the result of this comparison in an Output variable called NewerMajorVersion
.
It also sets two other output variables:
PatchVersion
- this is essentially the inverse value of the NewerMajorVersion
output variable
ShouldDeployApps
- this variable will be used later in a variable run condition to help control whether or not Applications A or B should be deployed as part of this deployment.
Set-up Project variables
The output variables created in the first script step can be referenced in project variables. Doing this can make your variable run conditions easier to understand by hiding some of the complexity away.
We need to add the following variables to support our variable run conditions:
Name |
Value |
Scope |
Description |
NewerMajorVersion |
#{Octopus.Action[Check deployment version].Output.NewerMajorVersion} |
|
Determines if we are deploying a major version |
PatchVersion |
#{Octopus.Action[Check deployment version].Output.PatchVersion} |
|
Determines if we are deploying a patch version |
Project.Deploy.Application.A |
#{if Project.Prompt.Deploy.Application.A}#{ShouldDeployApps}#{/if} |
|
Determines if Application A will be deployed |
Project.Deploy.Application.B |
#{if Project.Prompt.Deploy.Application.B}#{ShouldDeployApps}#{/if} |
|
Determines if Application B will be deployed |
Project.Prompt.Deploy.Application.A |
True |
|
User selectable checkbox to deploy App A |
|
False |
Production |
|
Project.Prompt.Deploy.Application.B |
True |
|
User selectable checkbox to deploy App B |
|
False |
Production |
|
ShouldDeployApps |
#{Octopus.Action[Check deployment version].Output.ShouldDeployApps} |
|
Determine if Apps should be deployed (for major or patch version) |
Note: The above indicates a prompted variable of type Checkbox.
The variables Project.Prompt.Deploy.Application.A
and Project.Prompt.Deploy.Application.B
have two values. One value is scoped to the Production environment. This is done to allow lower environments to be deployed to with minimal user interaction. You could, of course, change these to suit your requirements.
Add variable run conditions to our steps
Next, we need to add a variable run condition to our steps. Remember we have two types of steps to consider:
- Steps which should always run on a major version deployment.
- Steps which should always run on either a major or a patch deployment. Added to these steps is the ability to choose which of the owning applications (A or B) will be run by the use of the prompted variables we created earlier.
Add run condition to steps which always run on major version
Since we need to add the run condition to the steps which always run on a major version deployment, we use the variable NewerMajorversion
by choosing the Run Condition in the step, and selecting the Variable option and add the following expression:
#{if NewerMajorVersion == "True" }true#{/if}
We apply that to the steps Pre-Application step - Deploy when major release and Post-Application step - Deploy when major release like below:
Add run condition to application steps
Since we need to add the run condition to the steps which run on either a major or a patch version deployment, we use a different variable to the one used for the major version variable run condition.
For steps with Application A in the name we use the following variable expression:
#{if Project.Deploy.Application.A == "True" }true#{/if}
For steps with Application B in the name we use the following variable expression:
#{if Project.Deploy.Application.B == "True" }true#{/if}
Choosing which application to deploy:
When running the deployment to the Production, you will be prompted for a choice of which applications to deploy:
Example deployment of a minor version
In the screenshot below, Tenant A previously had version 1.0.4
deployed to Production, and now we are deploying version 1.0.5
:
Since this was considered a patch version:
- Steps 3 and 8 are skipped as they only run on a major version deployment.
- Application A is deployed since we opted to deploy by checking the box of the using the prompted variable.
- Application B is skipped since we opted to only deploy Application A.
Example deployment of a major version
In the screenshot below, Tenant C previously had version 1.0.4
deployed to Production, and now we are deploying version 2.0.6
:
Since this was considered a major version all steps were deployed.
It would have been possible to still choose to prevent either Application A or B from being deployed using the prompted variables, but that wasn’t utilized.
Octopus Samples instance
Check out our Samples instance to see this example (login as Guest
).