diff --git a/pipelines/productionBuild.yml b/pipelines/productionBuild.yml index 21d7b702b..a014a1055 100644 --- a/pipelines/productionBuild.yml +++ b/pipelines/productionBuild.yml @@ -63,8 +63,12 @@ extends: inputs: targetType: filePath filePath: 'scripts\ValidateUpdatedNugetVersion.ps1' - arguments: '-packageName "$(PACKAGE_NAME)" -projectPath "$(PROJECT_PATH)"' + # Look up the latest published version via the CFS central feed (which upstreams + # nuget.org) instead of api.nuget.org, to satisfy 1ES network isolation (CFSClean). + arguments: '-packageName "$(PACKAGE_NAME)" -projectPath "$(PROJECT_PATH)" -registrationsBaseUrl "https://pkgs.dev.azure.com/microsoftgraph/0985d294-5762-4bc2-a565-161ef349ca3e/_packaging/GraphDeveloperExperiences_Public/nuget/v3/registrations2"' pwsh: true + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) enabled: true - powershell: | dotnet workload install android ios maccatalyst diff --git a/scripts/ValidateUpdatedNugetVersion.ps1 b/scripts/ValidateUpdatedNugetVersion.ps1 index 7226a06dd..c496ae7a6 100644 --- a/scripts/ValidateUpdatedNugetVersion.ps1 +++ b/scripts/ValidateUpdatedNugetVersion.ps1 @@ -16,6 +16,14 @@ .Parameter projectPath Specifies the path to the project file. + +.Parameter registrationsBaseUrl + Base URL of the NuGet v3 registrations resource used to look up the latest published + version. Defaults to the public nuget.org endpoint. In network-isolated pipelines (CFSClean) + pass the CFS/Azure Artifacts feed registrations endpoint (which upstreams nuget.org) so the + lookup does not egress to api.nuget.org. When the URL is an Azure Artifacts feed it requires + authentication; set the SYSTEM_ACCESSTOKEN environment variable and it will be sent as a + Bearer token. #> Param( @@ -23,7 +31,10 @@ Param( [string]$packageName, [parameter(Mandatory = $true)] - [string]$projectPath + [string]$projectPath, + + [parameter(Mandatory = $false)] + [string]$registrationsBaseUrl = "https://api.nuget.org/v3/registration5-gz-semver2" ) [xml]$xmlDoc = Get-Content $projectPath @@ -40,18 +51,26 @@ $currentProjectVersion = [System.Management.Automation.SemanticVersion]"$version # API is case-sensitive $packageName = $packageName.ToLower() -$url = "https://api.nuget.org/v3/registration5-gz-semver2/$packageName/index.json" +$url = "$($registrationsBaseUrl.TrimEnd('/'))/$packageName/index.json" + +# Azure Artifacts feed endpoints require authentication; send the pipeline access token when +# available. Public nuget.org ignores the header. +$headers = @{} +if ($env:SYSTEM_ACCESSTOKEN) { + $headers["Authorization"] = "Bearer $env:SYSTEM_ACCESSTOKEN" +} # Call the NuGet API for the package and get the current published version. Try { - $nugetIndex = Invoke-RestMethod -Uri $url -Method Get + $nugetIndex = Invoke-RestMethod -Uri $url -Method Get -Headers $headers } Catch { - if ($_.ErrorDetails.Message && $_.ErrorDetails.Message.Contains("The specified blob does not exist.")) { + $statusCode = $_.Exception.Response.StatusCode.value__ + if ($statusCode -eq 404 -or ($_.ErrorDetails.Message -and $_.ErrorDetails.Message.Contains("The specified blob does not exist."))) { Write-Host "No package exists. You will probably be publishing $packageName for the first time." Exit # exit gracefully } - + Write-Host $_ Exit 1 }