Reputation: 6367
In TFS 2018 we may "Batch changes while a build is in progress," so that if a Git push occurs while a build is in progress the second one waits for the first to complete. In this way, we can stop multiple builds from running simultaneously.
However, there doesn't seem to be a similar option for releases.
Given my severely limited bandwidth, a given release can take far longer to complete than the build that triggered it. It's quite possible that this second build, even when queued, will trigger a new release when one is already in progress. I need to queue the entire pipeline until the current release finishes, not just the build.
I've been able to do this with a clunky and brittle series of PowerShell scripts (which is tedious to configure in its current state), but I'd like something a little more solid if possible.
How can I best accomplish this?
Test-PipelineStatus.ps1
$BuildDefinitionName = (Get-Item Env:BUILD_DEFINITIONNAME).Value
$ArtifactsDirectory = (Get-Item Env:BUILD_ARTIFACTSTAGINGDIRECTORY).Value
$SourcesDirectory = (Get-Item Env:BUILD_SOURCESDIRECTORY).Value
$LocatorFilePath = "$ArtifactsDirectory\Locator.txt"
$StatusDirectory = "$SourcesDirectory\Pipeline"
$StatusFilePath = "$StatusDirectory\Status.txt"
Set-Content $LocatorFilePath $StatusFilePath
If ((Test-Path $StatusDirectory) -eq $False) {
Write-Output "Creating pipeline status directory"
New-Item $StatusDirectory -ItemType Directory
}
Write-Output "Getting current pipeline status"
If (Test-Path $StatusFilePath) {
$Status = Get-Content $StatusFilePath
If ($Status -eq "Stopped") {
Write-Output "Setting current pipeline status to [Running]"
Set-Content $StatusFilePath "Running"
} Else {
Write-Error "Pipeline [$BuildDefinitionName] is already in progress. Failing this build."
Exit 1
}
} Else {
Write-Output "Setting current pipeline status to [Running]"
Set-Content $StatusFilePath "Running"
}
Get-StatusFilePath.ps1
$ArtifactsDirectory = (Get-Item Env:SYSTEM_ARTIFACTSDIRECTORY).Value
$ReleaseDefinition = (Get-Item Env:RELEASE_DEFINITIONNAME).Value
$LocatorFilePath = "$ArtifactsDirectory\$ReleaseDefinition\drop\Locator.txt"
$StatusFilePath = Get-Content $LocatorFilePath
Write-Output "Setting variable [StatusFilePath] to [$StatusFilePath]"
Write-Host "##vso[task.setvariable variable=StatusFilePath]$StatusFilePath"
Remove-Item $LocatorFilePath
Set-ReleaseComplete.ps1
[CmdletBinding()]
param(
[Parameter(Mandatory)][string] $StatusFilePath
)
Write-Output "Marking pipeline as complete"
Set-Content $StatusFilePath -Value "Stopped"
Upvotes: 0
Views: 285
Reputation: 59020
You can accomplish this within the release definition editor, nothing special required. For all of the environments in the release, under the pre-deployment conditions (where you'd set pre-deployment approvals and gates), expand the deployment queue settings and change the number of parallel deployments to 1, with subsequent releases set to deploy latest and cancel the others.
This way, if you're running release 1 and release 2, 3, 4, 5, and 6 get queued up, it will cancel 2-5 and deploy 6 when 1 finishes.
Upvotes: 1