Modules/businessdev.ALbuild.Feeds/Public/Invoke-BcPackagePromotion.ps1
|
function Invoke-BcPackagePromotion { <# .SYNOPSIS Promotes a published NuGet package version to a view on an Azure DevOps Artifacts feed. .DESCRIPTION Azure DevOps Artifacts feeds expose 'views' (e.g. @Prerelease, @Release). Promoting a package version to a view lets partners consume it from a view-scoped feed URL (.../_packaging/<feed>@Prerelease/nuget/v3/index.json), which is how ALbuild distributes prerelease (dev) and release (master) app packages from one feed. The view assignment is a one-shot PATCH against the Azure DevOps Packaging REST API (it is not part of the NuGet protocol). The feed's v3 index URL is parsed to derive the organisation, optional project and feed name. Promotion is OPT-IN: when -View is not supplied the cmdlet is a no-op and returns $true, so callers can pass the parameter through unconditionally. .PARAMETER Url The feed's NuGet v3 service index URL (.../nuget/v3/index.json) on an Azure DevOps Artifacts host (pkgs.dev.azure.com or *.pkgs.visualstudio.com). .PARAMETER View Target view name, e.g. 'Prerelease' or 'Release' (any custom view name is accepted). When empty or omitted, no promotion is performed. .PARAMETER ApiKey The Azure DevOps PAT used for the REST call (a Packaging read/write token, the same one used to publish). .PARAMETER PackagePath Path to the .nupkg. The package id and version are read from its .nuspec. Mutually exclusive with -PackageId/-Version. .PARAMETER PackageId Explicit package id. Use with -Version instead of -PackagePath. .PARAMETER Version Explicit package version. Use with -PackageId instead of -PackagePath. .EXAMPLE Invoke-BcPackagePromotion -Url $feedUrl -PackagePath .\pkg.1.0.0.nupkg -View Prerelease -ApiKey $env:FEED_PAT .OUTPUTS System.Boolean ($true on success or when there is nothing to promote). #> [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'FromPackage')] [OutputType([bool])] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Url, [string] $View, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $ApiKey, [Parameter(ParameterSetName = 'FromPackage')] [string] $PackagePath, [Parameter(ParameterSetName = 'Explicit', Mandatory)] [ValidateNotNullOrEmpty()] [string] $PackageId, [Parameter(ParameterSetName = 'Explicit', Mandatory)] [ValidateNotNullOrEmpty()] [string] $Version ) # Opt-in: nothing to do without a target view. if ([string]::IsNullOrWhiteSpace($View)) { Write-ALbuildLog -Level Verbose 'No view requested; skipping promotion.' return $true } # Resolve the package identity, from the .nupkg's .nuspec when a path is given. if ($PSCmdlet.ParameterSetName -eq 'FromPackage') { if (-not $PackagePath) { throw 'Provide -PackagePath, or -PackageId and -Version.' } if (-not (Test-Path -LiteralPath $PackagePath)) { throw "Package not found: '$PackagePath'." } $identity = Get-BcNuspecIdentity -PackagePath $PackagePath $PackageId = $identity.Id $Version = $identity.Version } # Parse the Azure DevOps feed coordinates from the v3 index URL. $coords = ConvertTo-BcAzureDevOpsFeedCoordinate -Url $Url # Build the Packaging REST endpoint (project segment is optional for org-scoped feeds). $projectSegment = if ($coords.Project) { "$($coords.Project)/" } else { '' } $patchUrl = "$($coords.BaseUrl)/${projectSegment}_apis/packaging/feeds/$($coords.Feed)/nuget/packages/$PackageId/versions/$Version`?api-version=7.1-preview.1" $body = @{ views = @{ op = 'add'; path = '/views/-'; value = $View } } | ConvertTo-Json -Depth 4 -Compress if (-not $PSCmdlet.ShouldProcess("$PackageId $Version", "Promote to '$View' view on feed '$($coords.Feed)'")) { return $true } $headers = @{ Authorization = "Basic $([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("user:$ApiKey")))" 'Content-Type' = 'application/json' } try { Invoke-RestMethod -Uri $patchUrl -Method Patch -Headers $headers -Body $body -UseBasicParsing -ErrorAction Stop | Out-Null Write-ALbuildLog -Level Success "Promoted '$PackageId' $Version to the '$View' view." return $true } catch { throw "Failed to promote '$PackageId' $Version to the '$View' view on feed '$($coords.Feed)': $($_.Exception.Message)" } } |