Files
qsys-plugin-registry-beta/tools/packages.ps1
T
2026-07-23 23:43:18 -04:00

91 lines
4.1 KiB
PowerShell

<#
.SYNOPSIS
List and delete package versions in the Gitea NuGet registry.
.DESCRIPTION
Listing without -Token uses the anonymous NuGet v3 search endpoint - the
same view Q-SYS Designer gets, so it doubles as a feed health check.
Listing with -Token uses Gitea's management API and adds publish dates.
Deleting always requires -Token (package write scope).
.EXAMPLE
./tools/packages.ps1 -List -Owner jodamaster
./tools/packages.ps1 -List -Owner jodamaster -Id ExamplePlugin -Token $env:GITEA_TOKEN
./tools/packages.ps1 -Delete -Owner jodamaster -Id ExamplePlugin -Version 1.0.0 -Token $env:GITEA_TOKEN
#>
[CmdletBinding(DefaultParameterSetName = "List")]
param(
[Parameter(ParameterSetName = "List")] [switch]$List,
[Parameter(ParameterSetName = "Delete", Mandatory)] [switch]$Delete,
[string]$GiteaUrl = "https://3f4dzl.gitea.cloud",
[Parameter(Mandatory)] [string]$Owner,
[Parameter(ParameterSetName = "List")]
[Parameter(ParameterSetName = "Delete", Mandatory)]
[string]$Id,
[Parameter(ParameterSetName = "Delete", Mandatory)] [string]$Version,
[string]$Token, # required for -Delete; optional for -List (adds publish dates)
[switch]$Force # skip the delete confirmation prompt
)
$ErrorActionPreference = "Stop"
$base = $GiteaUrl.TrimEnd('/')
$headers = @{}
if ($Token) { $headers["Authorization"] = "token $Token" }
# ---------------- Delete ----------------
if ($PSCmdlet.ParameterSetName -eq "Delete") {
if (-not $Token) { throw "Deleting requires -Token (package write scope)." }
if (-not $Force) {
$answer = Read-Host "Delete $Id $Version from $Owner's registry? This is immediate and permanent. [y/N]"
if ($answer -notmatch '^[Yy]') { Write-Host "Aborted."; exit 0 }
}
$uri = "$base/api/packages/$Owner/nuget/$Id/$Version"
Invoke-RestMethod -Uri $uri -Headers $headers -Method Delete | Out-Null
Write-Host "Deleted $Id $Version." -ForegroundColor Green
Write-Host "Note: Q-SYS expects strictly ascending versions - prefer publishing a higher"
Write-Host "version over deleting and re-using a version number (clients may have cached it)."
exit 0
}
# ---------------- List ----------------
if ($Token) {
# Management API: full info including publish dates (requires sign-in on Gitea Cloud)
$all = @(); $page = 1
while ($true) {
$uri = "$base/api/v1/packages/$($Owner)?type=nuget&limit=50&page=$page"
$batch = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get
if (-not $batch -or $batch.Count -eq 0) { break }
$all += $batch
if ($batch.Count -lt 50) { break }
$page++
}
if ($Id) { $all = $all | Where-Object { $_.name -ieq $Id } }
if (-not $all -or $all.Count -eq 0) { Write-Host "No packages found."; exit 0 }
$all | Sort-Object name, created_at | Group-Object name | ForEach-Object {
Write-Host "`n$($_.Name)" -ForegroundColor Cyan
$_.Group | ForEach-Object {
$created = ([datetime]$_.created_at).ToLocalTime().ToString("yyyy-MM-dd HH:mm")
Write-Host (" {0,-20} published {1}" -f $_.version, $created)
}
}
} else {
# Anonymous NuGet v3 search - exactly what Q-SYS Designer sees
$q = if ($Id) { $Id } else { "" }
$uri = "$base/api/packages/$Owner/nuget/query?q=$q&skip=0&take=100"
$result = Invoke-RestMethod -Uri $uri -Method Get
$items = $result.data
if ($Id) { $items = $items | Where-Object { $_.id -ieq $Id } }
if (-not $items -or $items.Count -eq 0) { Write-Host "No packages visible in the anonymous feed for '$Owner'."; exit 0 }
foreach ($pkg in $items) {
Write-Host "`n$($pkg.id) (latest: $($pkg.version))" -ForegroundColor Cyan
foreach ($v in $pkg.versions) { Write-Host " $($v.version)" }
Write-Host " Designer 'Add Personal Package' URL:" -ForegroundColor DarkGray
Write-Host " $base/api/packages/$Owner/nuget/registration/$($pkg.id)/index.json" -ForegroundColor Yellow
}
Write-Host "`n(Anonymous view = what Q-SYS Designer sees. Add -Token for publish dates.)"
}
Write-Host ""