Due to the nature of the build and release services in TFS, strange things can happen.
Just discovered that we had some builds that was marked “retained by release”, as usual, but looking at the details pane, there wasn’t any related deployments, so we wasn’t able to delete those builds.
So headed over to the PS console and kicked the TFS REST API, for some investigation.
Each build has a “RetainedByRelease” flag, that corespond to the state in TFS, but I also needed to verify if the artifacts were used in any deployment.
So I came up with a smal script that can find the troubled build in a project and optionally fix them
Microsoft have confirmed this issue, and expected fix should be available in 19Q1
Enjoy
$tfsServerURL = "HTTP://[TFSSERVER]:8080/tfs/defaultcollection" $TFSProject = [TFSProject] #Set to $true to update builds by settingretainingByRelease= false $CorrectError = $false $URL = "$($tfsServerURL)/$($TFSProject)" #Get all builddefinitions in Project $Buildefinitions = (Invoke-RestMethod -Uri ($URL + '/_apis/build/definitions?api-version=3.2') -Method GET -UseDefaultCredentials).value foreach($Builddefiniton in $Buildefinitions) { Write-Output "Searching in $($Builddefiniton.name)" #Get Builds with keepforever = false and retainedByRelease = true $Builds = (Invoke-RestMethod -Uri ($URL + '/_apis/build/builds?definitions=' + $buildDefinition.id + '&statusFilter=completed&api-version=3.2') -Method GET -UseDefaultCredentials).value | where {$_.keepForever -eq $False -and $_.retainedByRelease -eq $true} #Get releases linked to the build foreach ($build in $Builds) { if ((Invoke-RestMethod -Uri ($URL + '/_apis/release/releases?api-version=3.2-preview&artifactTypeId=Build&artifactVersionId=' + $build.id) -Method GET -UseDefaultCredentials).count -eq 0) { Write-Output "`t$($build.buildNumber) is marked retained by release, but have no deployments" If ($CorrectError) { Invoke-RestMethod -Uri ($URL + '/_apis/build/builds/'+ $build.id + '?api-version=3.2') -Method Patch -UseDefaultCredentials -Body (ConvertTo-Json @{"retainedByRelease"='false'}) -Headers @{"content-type" = "application/json"} | Out-Null Write-Output "`tFixed" } } } }