Kirsten
Kirsten

Reputation: 18046

Build pipeline does not delete

In the Azure DevOps portal, I select a pipeline, then the [...] menu, then Delete.

I see a message asking:

Are you sure? This action cannot be undone. This will permanently delete the pipeline 'vt3e (1)'. Deletion includes all builds and associated artifacts.

I type in the pipeline name and click OK but the pipeline does not delete.

I have waited some hours.

F12 in Chrome shows an error in the console:

ms.vss-build-web.common-library.__y__CePsj5f5zdcIK.min.js:18 Error: One or more builds associated with the requested pipeline(s) are retained by a release. The pipeline(s) and builds will not be deleted

I am trying to follow the answer given by David D, but when I go to delete a release I get a message

VS402946: 'Release-8' cannot be deleted as it is currently deployed on stage(s) Stage 1.

The issue is logged at Microsoft

Upvotes: 58

Views: 62077

Answers (15)

Murali
Murali

Reputation: 111

enter image description here

enter image description here

I have facing same below issue

One or more builds associated with the requested pipeline(s) are retained by a release. The pipeline(s) and builds will not be deleted.

It is simple to solve this, just open the pipeline which you want to delete and if you have seen this in your pipeline just click on three dots [View Retention leases]and open the View retention leases and click on Remove all option and close the pop-up.[Run retention]. Once you perform this action you're now free to go and delete the pipeline which you want.

Upvotes: 11

MoeHamdan
MoeHamdan

Reputation: 76

Now you can click on more options for each build, and click on "view retention releases", not all builds will have but some will. You will need then to remove these retentions. After removing them, you will be able to delete the pipeline. enter image description here

enter image description here

Upvotes: 0

sprash
sprash

Reputation: 345

  1. Open the pipeline

  2. Click the three dots on any retained build(there should be many) > Select View retention leases

  3. Give Remove all in the menu that opens

After this, you will be able to delete the pipeline. PFB the screenshot of pop-up expected.

enter image description here

Upvotes: 0

Luke Vanzweden
Luke Vanzweden

Reputation: 646

You can also just temporarily choose to retain nothing, then delete what you want, then revert.

enter image description here

Upvotes: -1

Pawan Dubey
Pawan Dubey

Reputation: 324

Go to the pipeline, and check retention for each run, and if found delete them. This did solve my problem of deleting a pipeline.

Upvotes: 0

Andrew Zaitsev
Andrew Zaitsev

Reputation: 353

To fix that problem you can:

  1. clone failed stage in the current release pipeline configuration
  2. delete the original stage and use a clone instead of a deleted stage with a different name.
  3. delete the previous failed release (*it will be possible)
  4. after deleting you can rename the copied stage again.
  5. enjoy

Upvotes: 0

Ari
Ari

Reputation: 531

February 2022 Version of Script to delete a Build Pipeline including all Builds and Leases:

#Azure DevOps Personal Access Token
# https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows

$personalAccessToken = "<Enter your personal access token here>"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalAccessToken)"))
$header = @{authorization = "Basic $token"}

$organization = "<Enter your Azure DevOps Organization here>"
$project = "<Enter your Project Name here>"

$pipelineName = "<Enter the Build Pipeline Definition Name to be deleted here>"

#Get all build definitions
# API: GET https://dev.azure.com/{organization}/{project}/_apis/build/definitions/{definitionId}?api-version=6.0
$url = "https://dev.azure.com/$organization/$project/_apis/build/definitions?api-version=6.0"
$allBuildDefinitions = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header

$allBuildDefinitions.value | Where-Object {$_.name -eq $pipelineName} | ForEach-Object {
    Write-Host $_.id $_.name $_.queueStatus
 
    # For debugging reasons, just to be sure that we don't delete the wrong build pipeline
    if ( $_.name -ne $pipelineName ) {
        return;
    }

    #Get all Builds for a Definition
    # API: GET https://dev.azure.com/{organization}/{project}/_apis/build/builds?definitions={definitions}&queues={queues}&buildNumber={buildNumber}&minTime={minTime}&maxTime={maxTime}&requestedFor={requestedFor}&reasonFilter={reasonFilter}&statusFilter={statusFilter}&resultFilter={resultFilter}&tagFilters={tagFilters}&properties={properties}&$top={$top}&continuationToken={continuationToken}&maxBuildsPerDefinition={maxBuildsPerDefinition}&deletedFilter={deletedFilter}&queryOrder={queryOrder}&branchName={branchName}&buildIds={buildIds}&repositoryId={repositoryId}&repositoryType={repositoryType}&api-version=6.0
    $url = "https://dev.azure.com/$organization/$project/_apis/build/builds?definitions=" + $_.id + "&api-version=6.0"
    $allBuildsOfDefinition = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header
 
    #Process each Build of Definition
    $allBuildsOfDefinition.value | Where-Object {$_.retainedByRelease -eq "True"} | Sort-Object id | ForEach-Object {
        #Report on retain status
        Write-Host "Build Id:" $_.id " retainedByRelease:" $_.retainedByRelease

        #Get all Retention Leases for this Build
        # API: GET https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/leases?api-version=7.1-preview.1
        $url = "https://dev.azure.com/$organization/$project/_apis/build/builds/" + $_.id + "/leases?api-version=7.1-preview.1"
        $allLeasesOfBuild = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header

        #Delete each Lease of Build
        $allLeasesOfBuild.value | ForEach-Object {
            #Delete Lease
            # API: DELETE https://dev.azure.com/{organization}/{project}/_apis/build/retention/leases?ids={ids}&api-version=7.1-preview.2
            $url = "https://dev.azure.com/$organization/$project/_apis/build/retention/leases?ids=" + $_.leaseId + "&api-version=7.1-preview.2"
            Invoke-RestMethod -Uri $url -Method Delete -ContentType "application/json" -Headers $header

            #Report on Lease deleted
            Write-Host "Lease Id:" $_.leaseId " deleted"
        }

        #Delete Build
        # API: DELETE https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}?api-version=7.1-preview.7
        $url = "https://dev.azure.com/$organization/$project/_apis/build/builds/" + $_.id + "?api-version=7.1-preview.7"
        Invoke-RestMethod -Uri $url -Method Delete -ContentType "application/json" -Headers $header

        #Report on Build deleted
        Write-Host "Build Id:" $_.id " deleted"
    }

    #Delete the Build Definition
    # API: DELETE https://dev.azure.com/{organization}/{project}/_apis/build/definitions/{definitionId}?api-version=6.0
    $url = "https://dev.azure.com/$organization/$project/_apis/build/definitions/" + $_.id + "?api-version=6.0"
    Invoke-RestMethod -Uri $url -Method Delete -ContentType "application/json" -Headers $header
    
    Write-Host "Build Definition:" $pipelineName " (" $_.id ") deleted"
}
    
Write-Host "Habe fertig!"

Upvotes: 25

Naresh Nagpal
Naresh Nagpal

Reputation: 387

I used powershell to delete just my own build (instead of looping through all the build definitions)

$organization = "YourOrganization"
$project = "YourProject"
$personalAccessToken = "GetTokenFromAzureDevops"

$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalAccessToken)"))
$header = @{authorization = "Basic $token"}



$url = "https://dev.azure.com/$organization/$project/_apis/build/definitions?api-version=3.2"
Write-Host $url
$buildDefinitions = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header

function DeleteLease($definitionId) {
    $url = "https://dev.azure.com/$organization/$project/_apis/build/retention/leases?api-version=6.0-preview.1&definitionId=$definitionId"
    $leases = (Invoke-RestMethod -Method GET -Uri $url -ContentType "application/json" -Headers $header )

    foreach ($lease in $leases.value) {
        $leaseId = $lease.leaseId
        $url = "https://dev.azure.com/$organization/$project/_apis/build/retention/leases?ids=$($leaseId)&api-version=6.0-preview.1"
        $ignore = Invoke-RestMethod -Method DELETE -Uri $url -ContentType "application/json" -Headers $header
    }
}

DeleteLease "yourBuildDefinitionId"

Note :

  1. The PAT token can be created from Azure Devops Portal using below Sign in to your organization in Azure DevOps (https://dev.azure.com/{yourorganization})

From your home page, open your user settings, and then select Personal access tokens.

  1. To get the build definition Id- see the URL of build , it will have the ID in the URL itself.

Upvotes: 2

Carlos Online
Carlos Online

Reputation: 326

Microsoft now has an api to delete leases directly.

DELETE https://dev.azure.com/{organization}/{project}/_apis/build/retention/leases?ids={ids}&api-version=6.0-preview.1

https://learn.microsoft.com/en-us/rest/api/azure/devops/build/leases/delete?view=azure-devops-rest-6.0

How to:

  1. Enumerate build definitions
  2. Delete leases for each desired build definition
  3. Delete the build definition

Example:

$organization = "flintsones"
$project = "feed-dino"
$personalAccessToken = "****************"

$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalAccessToken)"))
$header = @{authorization = "Basic $token"}

function DeleteLease($definitionId) {
    $url = "https://dev.azure.com/$organization/$project/_apis/build/retention/leases?api-version=6.0-preview.1&definitionId=$definitionId"
    $leases = (Invoke-RestMethod -Method GET -Uri $url -ContentType "application/json" -Headers $header )

    foreach ($lease in $leases.value) {
        $leaseId = $lease.leaseId
        $url = "https://dev.azure.com/$organization/$project/_apis/build/retention/leases?ids=$($leaseId)&api-version=6.0-preview.1"
        $ignore = Invoke-RestMethod -Method DELETE -Uri $url -ContentType "application/json" -Headers $header
    }
}

$url = "https://dev.azure.com/$organization/$project/_apis/build/definitions?api-version=3.2"
Write-Host $url
$buildDefinitions = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header

foreach ($def in $builddefinitions.value) {
    Write-Host $def.id $def.queueStatus $def.name
    DeleteLease $def.id
}

Upvotes: 5

Matt Fricker
Matt Fricker

Reputation: 539

I get the same error if I try to delete a pipeline:

One or more builds associated with the requested pipeline(s) are retained by a release. The pipeline(s) and builds will not be deleted.

On the pipelines page go to the Runs tab, should see a list of records. If you click on the three dots to the right of the row you should see an option to View retention leases. If you Remove All you should then be able to remove that row. You will then need to repeat this step for every row in the the runs tab until all runs have been deleted.

Only then will you be able to delete the parent pipeline.

Upvotes: 5

Elliott
Elliott

Reputation: 2205

If you have deleted the release in question, but you still get this error, the solve for it is:

  1. Go to the build pipeline in question.
  2. Under the 'Runs' tab, open each "run" individually
  3. If a run is being retained, you'll see a white box at the top with verbiage like "This run has been retained forever by 82 (Pipeline)" and to right, you'll see a button "View Retention Releases". That's where you'll delete the one or more retention releases.
  4. You'll have to go through each "run" and repeat this process

If that white box/button isn't visible, that particular run isn't retained. You can confirm so by clicking the three dots in the top right corner and selecting "view retention releases"

Upvotes: 63

Reggi
Reggi

Reputation: 482

I came on the same problem last week and I updated a script from someone to work with the 5.1 API. This script will run over all builds that are retained by a release pipeline. You will need some tweaking of you don't want that all your builds are removed from releases.

$tfsServerURL = "https://dev.azure.com/{organisation}"
$TFSProject = "{project}"

$AzureDevOpsPAT = "{token}"
$AzureDevOpsAuthenicationHeader = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($AzureDevOpsPAT)"))}
 
#Set to $true to update builds by settingretainingByRelease= false
$CorrectError = $true
 
$URL = "$($tfsServerURL)/$($TFSProject)"
Write-Output $URL
#Get all builddefinitions in Project
$Buildefinitions = (Invoke-RestMethod -Uri ($URL + '/_apis/build/definitions?api-version=5.1') -Method GET -UseDefaultCredentials -Headers $AzureDevOpsAuthenicationHeader).value
 
foreach($Builddefiniton in $Buildefinitions)
{
    Write-Output "Searching in $($Builddefiniton.name) with id $($Builddefiniton.id)"
    #Get Builds with keepforever = false and retainedByRelease = true
    
    $Builds = (Invoke-RestMethod -Uri ($URL + '/_apis/build/builds?definitions=' + $Builddefiniton.id + '&api-version=5.1') -Method GET -UseDefaultCredentials -Headers $AzureDevOpsAuthenicationHeader).value | where {$_.keepForever -eq $False -and $_.retainedByRelease -eq $true}
     
    #Get releases linked to the build

    foreach ($build in $Builds)
    {
        If ($CorrectError)
        {
            Invoke-RestMethod -Uri ($URL + '/_apis/build/builds/'+ $build.id + '?api-version=5.1') -Method Patch -Body (ConvertTo-Json @{"retainedByRelease"='false'}) -UseDefaultCredentials -Headers $AzureDevOpsAuthenicationHeader -ContentType "application/json" | Out-Null
            Write-Output "`tFixed"
        }
    }
}

The PowerShell script will first fetch all build pipelines, then fetch all builds that are not kept infinitely and are retained by a release. If the CorrectError is set to true the script will then try to switch the retainedByRelease flag to false.

After I ran this script I was able to remove my build pipeline.

Upvotes: 15

Munish
Munish

Reputation: 31

Go to pipeline runs and click on 3 dots when you hover across each run. You will see an option for view retention leases. Click on that and then click on remove all. You have to do it for all the runs. Once deleted then try to delete the build pipeline.

Upvotes: 3

sishanov
sishanov

Reputation: 171

You just need to click on three dots menu button and select delete then it will make sure that you know what you are actually doing, check the " Automatically cancel any in-progress release deployments" and remove it

enter image description here

Upvotes: -4

David D
David D

Reputation: 539

I was having the same problem and tried different browsers, platforms etc. I found that by removing each release manually under the releases tab, going back to build and then trying to delete the pipeline again worked for me.

Upvotes: 30

Related Questions