你好Azure DevOps专家
我在Azure DevOps中确实有一些旧的构建管道,我想使用Power Shell删除它们。我编写了一个小的强大shell脚本,首先获得构建定义,然后获得构建id、名称等。在我可以删除定义之前,必须删除保留的释放。程序代码已经准备好了,但是API需要一个ownerId或userId或Minimal Retention租约。这就是我的挑战!
我阅读了文档https://learn.microsoft.com/en-us/rest/api/azure/devops/build/leases?view=azure-devops-rest-6.0和背后的代码(托管在GitHub https://github.com/microsoft/azure-devops-node-api/blob/470f9ca7bdfccd87e1c1fdea8023b8c3d2b1047a/api/interfaces/BuildInterfaces.ts#L2006上),但我不知道ownerId或userId是什么,或者我如何找到它。
$personalToken = "AzureDevOpsPersonalToken"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalToken)"))
$header = @{authorization = "Basic $token"}
$organization = "myOrga"
$project = "myProj"
$pipelineName = Read-Host "Please enter pipeline to delete"
#all build definitions
$url = "https://dev.azure.com/$organization/$project/_apis/build/definitions?api-version=6.0-preview.7"
$builddefinitions = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header
$builddefinitions.value | Sort-Object id|ForEach-Object {
Write-Host $_.id $_.name $_.queueStatus
if ( $_.name -ne $pipelineName ) {
return;
}
#all builds for a definition
$url = "https://dev.azure.com/$organization/$project/_apis/build/builds?definitions=" + $_.id + "&api-version=6.0-preview.5"
$builds = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header
$builds.value | Sort-Object id|ForEach-Object {
#report on retain status
Write-Host " BuildId:" $_.id " retainedByRelease:" $_.retainedByRelease
# ownerId UNKNOWN - where is this come from?
$url = "https://dev.azure.com/$organization/$project/_apis/build/retention/leases?ownerId=&api-version=6.0-preview.1"
$leases = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header
Write-Host $leases
#$url = "https://dev.azure.com/$organization/$project/_apis/build/retention/leases?ids=" + $_.id + "&api-version=6.0-preview.1"
#Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header
#Write-Host " BuildId:" $_.id " removed retentions"
#
#$url = "https://dev.azure.com/$organization/$project/_apis/build/builds/" + $_.id + "?api-version=6.0-preview.1"
#Invoke-RestMethod -Uri $url -Method DELETE -ContentType "application/json" -Headers $header
#Write-Host " BuildId:" $_.id " deleted"
}
#$url = "https://dev.azure.com/$organization/$project/_apis/build/definitions/" + $_.id + "?api-version=6.0-preview.1"
#Invoke-RestMethod -Uri $url -Method Delete -ContentType "application/json" -Headers $header
#
#Write-Host " Pipeline:" $pipelineName " (" $_.id ") deleted"
Write-Host
}
你能帮我吗?先谢谢你天奴
Azure DevOps Portal中的内容经常变化。在2022年2月,我从几个Stackoverflow帖子中编写了自己的脚本,以删除旧的构建管道,他们的构建和租赁。
#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!"
与此同时,我在https://tenbulls.co.uk/2020/03/25/delete-old-build-definitions-in-azure-devops/上找到了一个不知名的人。
诀窍是修补retainedByRelease=false.
$url = "https://dev.azure.com/$organization/$project/_apis/build/builds/" + $_.id + "?api-version=6.0-preview.5"
Invoke-RestMethod -Uri $url -Method Patch -Body (ConvertTo-Json @{"retainedByRelease"="false"}) -ContentType "application/json" -Headers $header
$personalToken = "AzureDevOpsPersonalToken"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalToken)"))
$header = @{authorization = "Basic $token"}
$organization = "myOrga"
$project = "myProj"
$pipelineName = Read-Host "Please enter pipeline to delete"
#all build definitions
$url = "https://dev.azure.com/$organization/$project/_apis/build/definitions?api-version=6.0-preview.7"
$builddefinitions = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header
$builddefinitions.value | Sort-Object id|ForEach-Object {
Write-Host $_.id $_.name $_.queueStatus
if ( $_.name -ne $pipelineName ) {
return;
}
#all builds for a definition
$url = "https://dev.azure.com/$organization/$project/_apis/build/builds?definitions=" + $_.id + "&api-version=6.0-preview.5"
$builds = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $header
$builds.value | where {$_.retainedByRelease -eq "True"} | Sort-Object id|ForEach-Object {
#report on retain status
Write-Host " BuildId:" $_.id " retainedByRelease:" $_.retainedByRelease
#api call for a build
$url = "https://dev.azure.com/$organization/$project/_apis/build/builds/" + $_.id + "?api-version=6.0-preview.5"
Invoke-RestMethod -Uri $url -Method Patch -Body (ConvertTo-Json @{"retainedByRelease"="false"}) -ContentType "application/json" -Headers $header
}
$url = "https://dev.azure.com/$organization/$project/_apis/build/definitions/" + $_.id + "?api-version=6.0-preview.1"
Write-Host $url
Invoke-RestMethod -Uri $url -Method Delete -ContentType "application/json" -Headers $header
Write-Host " Pipeline:" $pipelineName " (" $_.id ") deleted"
}
Write-Host "done"
仅供参考,我运行了上面的脚本,仍然有问题,它不允许我删除所有保留的构建。相反,我必须查询当前构建的租约并单独删除它们,然后才能删除构建。我从另一个答案修改的循环如下:
$builds.value | where {$_.retainedByRelease -eq "True"} | Sort-Object id|ForEach-Object {
#report on retain status
Write-Host " BuildId:" $_.id " retainedByRelease:" $_.retainedByRelease
#api call for a build
$url = "https://dev.azure.com/$organization/$project/_apis/build/builds/" + $_.id + "?api-version=6.1-preview.7"
#Get All leases for the current build
$leaseurl = "https://dev.azure.com/$organization/$project/_apis/build/builds/" + $_.id + "/leases?api-version=6.1-preview.1"
$result = Invoke-RestMethod -Uri $leaseurl -Method Get -Headers $header
if ($result.count -gt 0){
$result.value | ForEach-Object {
$deleteLeaseUrl = "https://dev.azure.com/$organization/$project/_apis/build/retention/leases?ids=" + $_.leaseId + "&api-version=6.1-preview.2"
Invoke-RestMethod -Uri $deleteLeaseUrl -Method DELETE -Body "{}" -ContentType "application/json" -Headers $header
}
}
Invoke-RestMethod -Uri $url -Method Get -Headers $header
Invoke-RestMethod -Uri $url -Method DELETE -Headers $header
}