如何删除 DevOps 工件中的所有上游包?

How do I remove all upstream packages in DevOps artifacts?

我们不想再在我们的工件提要中使用上游源,但出于某种原因,即使在删除上游连接后,这些包仍然存在。有没有办法删除这些包?我已经尝试删除所有软件包的最新版本,但它的建议是:它只删除第一个版本并保持所有其他软件包版本不变。

您可以设置 retention policy 这也适用于来自上游源的包。

Over time, the number of versions for each package being hosted in your feed can grow quickly. You can set up retention policies to automatically delete old packages and save storage space.

  • maximum number of versions: allow you to chose how many versions of a package you want to keep.
  • days to keep recently downloaded packages. Packages will be deleted only if they have not been downloaded for the number of days set in here.

我知道这并不理想,因为它也会影响您的包裹。但除此之外,您需要手动将它们全部删除。基本上,它们就像您自己的包裹一样对待。这就是你的问题。

When you enable retention policies, a version of a package will be deleted when both of the following criteria are met:

  • The number of published versions of that package reaches the maximum number of versions limit, AND
  • A version of that package has not been downloaded within the number of days to keep recently downloaded packages.

How do I remove all upstream packages in DevOps artifacts?

事实上,目前还没有这种开箱即用的方法来删除 DevOps 工件中的所有上游包(包括所有版本)。

有一个封闭的用户意见:Delete Upstream Source Cached Packages。如果您对此功能感兴趣,可以打开一个新的用户语音建议;我愿意投给你

作为解决方法,我们可以循环遍历 REST API (NuGet - Delete Package Version) 以删除上游包的所有版本:

DELETE https://pkgs.dev.azure.com/{organization}/{project}/_apis/packaging/feeds/{feedId}/nuget/packages/{packageName}/versions/{packageVersion}?api-version=6.0-preview.1

首先,我们需要通过 REST API (Feed Management - Get Feed) and all packages in that feed (Artifact Details - Get Packages) 获取 NuGet 提要的 FeedId

这里重要的一点是我们需要确定这些包中有哪些来自上游源。有 属性 directUpstreamSourceId 用于 REST API (Artifact Details - Get Packages):

现在我们可以根据该字段是否存在来判断该包是否为上游源码包

其次,在我们得到所有上游源码包的Id之后,我们可以通过REST循环API(Artifact Details - Get Package Versions)来得到包的所有版本。

第三,在获取所有版本后,我们可以通过 REST API (NuGet - Delete Package Version) 循环删除该包的所有版本。

下面是我用于测试的 PowerShell 脚本:

$connectionToken="Your PAT Here"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
    
$PackagesUrl = "https://feeds.dev.azure.com/{organization}/{project}/_apis/packaging/Feeds/{feedId}/packages?api-version=6.0-preview.1" 
    
Write-Host "URL: $PackagesUrl"
    
$PackagesInFeed = (Invoke-RestMethod -Uri $PackagesUrl -Method Get -UseDefaultCredential -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)})
    
$packagesId = $PackagesInFeed.value.id
    
$UpstreamSourceParameters= $PackagesInFeed.value.versions | Get-Member -MemberType Properties
    
$UpstreamSource = $UpstreamSourceParameters[0].name
    
Write-Host "The Upstream Source Parameter name: $UpstreamSource"
    
ForEach ($PI in $packagesId)
{
    if ($UpstreamSource -ne $null)
    {
          
        $PackageVersionUrl = "https://feeds.dev.azure.com/{organization}/{project}/_apis/packaging/Feeds/{feedId}/packages/$($PI)/versions?api-version=6.0-preview.1"                 
        $PackageVersions = (Invoke-RestMethod -Uri $PackageVersionUrl -Method Get -UseDefaultCredential -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)})
    
        $PackageNameUrl = "https://feeds.dev.azure.com/{organization}/{project}/_apis/packaging/Feeds/{feedId}/packages/$($PI)?api-version=6.0-preview.1"                 
        $PackageNames = (Invoke-RestMethod -Uri $PackageNameUrl -Method Get -UseDefaultCredential -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)})
            
        $VersionsId = $PackageVersions.value.version
    
        $packageName = $PackageNames.name
            
        Write-Host "Package Versions: $VersionsId"
    
        Write-Host "Package Name: $packageName"
    
        ForEach ($VI in $VersionsId)
        {
            $DeleteUrl = "https://pkgs.dev.azure.com/{organization}/{project}/_apis/packaging/feeds/{feedId}/nuget/packages/$($packageName)/versions/$($VI)?api-version=6.0-preview.1"                   
            $Member = (Invoke-RestMethod -Uri $DeleteUrl -Method DELETE -UseDefaultCredential -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)})
        }
   
    }
    elseif($targetTask.result -eq "Failed")
    {
        Write-Host ("This is package not from upstream source!")
    }
    
}

注意:如果您的 Feed 范围是组织,请在 REST API URL.[=26= 中删除字段 /{project} ]

以下是我的测试结果。初始数字是 317,如您在上一个屏幕截图中所见。我中止了脚本以避免删除我所有的上游包。