Reputation: 866
We no longer would like to use upstream sources in our artifacts feed, but for some reason the packages still exist even after removing the upstream connection. Is there a way to remove these packages? I have tried removing latest version on all packages, but that does what it suggests: It only removes the first version and leaves all the other package versions intact.
Upvotes: 2
Views: 2604
Reputation: 76740
How do I remove all upstream packages in DevOps artifacts?
Indeed, there is no such out of the box way to remove all upstream packages (including all versions) in DevOps artifacts at this moment.
There is a closed User Voice about it: Delete Upstream Source Cached Packages. If you are interested in this feature, you can open a new User Voice suggestion; I am willing to vote for you.
As workaround, we could loop through the REST API (NuGet - Delete Package Version) to delete all versions of upstream packages:
DELETE https://pkgs.dev.azure.com/{organization}/{project}/_apis/packaging/feeds/{feedId}/nuget/packages/{packageName}/versions/{packageVersion}?api-version=6.0-preview.1
First, we need to get the FeedId
for the NuGet feed by the REST API (Feed Management - Get Feed) and all packages in that feed (Artifact Details - Get Packages).
An important point here is that we need to determine which of these packages are from upstream sources. There is property directUpstreamSourceId
for the REST API (Artifact Details - Get Packages):
Now, we can judge whether the package is an upstream source package based on whether this field exists.
Second, after we getting the Id
of all upstream source packages, we can loop through the REST API (Artifact Details - Get Package Versions) to get all versions for the package.
Third, after getting the all the versions, we can loop through the REST API (NuGet - Delete Package Version) to delete all versions of that packages.
Below is my PowerShell script for testing this:
$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!")
}
}
Note: If your feed scope is organization, remove the field /{project}
in the REST API URL.
The following are my test results. The initial number was 317
, as you can see in the previous screenshot. I aborted the script to avoid deleting all my upstream packages.
Upvotes: 5
Reputation: 2824
This did it for me:
Upvotes: -1
Reputation: 40603
You can set retention policy which also applies to packages from upstream sources.
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.
I understood that this is not ideal, as it will also impact your packages. But otherwise you need to go manually and delete them all. Basically, they are treat like your own packages. And this is the issue in your case.
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.
Upvotes: 1