From b7c3b12f132d09fc98895f6a981b58a3c563efe5 Mon Sep 17 00:00:00 2001 From: "Gavin Barron (from Dev Box)" Date: Tue, 4 Aug 2026 17:49:52 -0700 Subject: [PATCH 1/2] fix(ci): avoid blocked NuGet registration endpoint Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 03d194c7-5fba-4802-a182-3b3ef5c5c0ab --- scripts/ValidateUpdatedNugetVersion.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/ValidateUpdatedNugetVersion.ps1 b/scripts/ValidateUpdatedNugetVersion.ps1 index b89c26a39de1..643161af6436 100644 --- a/scripts/ValidateUpdatedNugetVersion.ps1 +++ b/scripts/ValidateUpdatedNugetVersion.ps1 @@ -36,7 +36,7 @@ $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 = "https://azuresearch-usnc.nuget.org/query?q=packageid:$packageName&prerelease=true&semVerLevel=2.0.0" # Call the NuGet API for the package and get the current published version. Try { @@ -52,7 +52,7 @@ Catch { Exit 1 } -$currentPublishedVersion = [System.Management.Automation.SemanticVersion]$nugetIndex.items[$nugetIndex.items.Count-1].upper +$currentPublishedVersion = [System.Management.Automation.SemanticVersion]$nugetIndex.data[0].version # Validate that the version number has been updated. if ($currentProjectVersion -le $currentPublishedVersion) { From efb22192721ccd8f4f5ddf6282a6f199dba9bbf3 Mon Sep 17 00:00:00 2001 From: "Gavin Barron (from Dev Box)" Date: Tue, 4 Aug 2026 18:00:30 -0700 Subject: [PATCH 2/2] fix(pipelines): route NuGet version check through CFS feed to resolve CFSClean violation The 'Validate updated version' PowerShell@2 step in the build job called the public NuGet.org search API (azuresearch-usnc.nuget.org) directly via Invoke-RestMethod. The pipeline's Network Isolation task flags this as a CFSClean (SFI-ES4.2.4) violation for connections to api.nuget.org made by a PowerShell process, reported in the build job's 'Stop Network Isolation' step. ValidateUpdatedNugetVersion.ps1 now accepts a -nugetConfigPath parameter and queries the package's published versions via 'dotnet package search' against the already-configured Central Feed Service nuget.config (the same feed used by 'dotnet restore'), which proxies to NuGet.org as an upstream source. This keeps the version check functional while routing the network call through the CFS-approved path instead of nuget.org directly. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- pipelines/ci-build.yml | 2 +- scripts/ValidateUpdatedNugetVersion.ps1 | 41 +++++++++++++++++-------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/pipelines/ci-build.yml b/pipelines/ci-build.yml index a1c15f0d7386..86c9318f03dc 100644 --- a/pipelines/ci-build.yml +++ b/pipelines/ci-build.yml @@ -88,7 +88,7 @@ extends: inputs: targetType: filePath filePath: '$(Build.SourcesDirectory)\scripts\ValidateUpdatedNugetVersion.ps1' - arguments: '-packageName "Microsoft.Graph.Beta" -projectPath "$(Build.SourcesDirectory)\src\Microsoft.Graph\Microsoft.Graph.Beta.csproj"' + arguments: '-packageName "Microsoft.Graph.Beta" -projectPath "$(Build.SourcesDirectory)\src\Microsoft.Graph\Microsoft.Graph.Beta.csproj" -nugetConfigPath "$(Build.SourcesDirectory)\nuget.config"' pwsh: true enabled: true - powershell: | diff --git a/scripts/ValidateUpdatedNugetVersion.ps1 b/scripts/ValidateUpdatedNugetVersion.ps1 index 643161af6436..4baf194f152e 100644 --- a/scripts/ValidateUpdatedNugetVersion.ps1 +++ b/scripts/ValidateUpdatedNugetVersion.ps1 @@ -16,6 +16,12 @@ .Parameter projectPath Specifies the path to the project file. + +.Parameter nugetConfigPath + Specifies the path to the nuget.config file that points at the organization's Central + Feed Service (CFS) NuGet feed. The feed is used (instead of calling the public NuGet.org + API directly) so this check stays compliant with the SFI-ES4.2.4 / CFSClean network + isolation policy enforced on the build agents. #> Param( @@ -23,7 +29,10 @@ Param( [string]$packageName, [parameter(Mandatory = $true)] - [string]$projectPath + [string]$projectPath, + + [parameter(Mandatory = $true)] + [string]$nugetConfigPath ) [xml]$xmlDoc = Get-Content $projectPath @@ -34,25 +43,31 @@ $versionString = $xmlDoc.Project.PropertyGroup[0].Version # System.Version, get the version prefix. $currentProjectVersion = [System.Management.Automation.SemanticVersion]"$versionString" -# API is case-sensitive -$packageName = $packageName.ToLower() -$url = "https://azuresearch-usnc.nuget.org/query?q=packageid:$packageName&prerelease=true&semVerLevel=2.0.0" - -# Call the NuGet API for the package and get the current published version. +# Look up the package's published versions through the CFS feed configured in +# $nugetConfigPath (see the 'Create nuget.config (central feed)' pipeline step) rather than +# calling the public NuGet.org search API directly. The feed has NuGet.org configured as an +# upstream source, so it transparently proxies searches for packages -- including this one -- +# that live upstream, keeping this check both functional and CFSClean-compliant. Try { - $nugetIndex = Invoke-RestMethod -Uri $url -Method Get + $searchResultJson = dotnet package search $packageName --configfile $nugetConfigPath --exact-match --prerelease --format json + if ($LASTEXITCODE -ne 0) { + throw "dotnet package search exited with code $LASTEXITCODE" + } + + $searchResult = $searchResultJson | ConvertFrom-Json + $matchingPackages = $searchResult.searchResult | ForEach-Object { $_.packages } | Where-Object { $_.id -ieq $packageName } } Catch { - if ($_.ErrorDetails.Message && $_.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 } -$currentPublishedVersion = [System.Management.Automation.SemanticVersion]$nugetIndex.data[0].version +if (-not $matchingPackages) { + Write-Host "No package exists. You will probably be publishing $packageName for the first time." + Exit # exit gracefully +} + +$currentPublishedVersion = ($matchingPackages | ForEach-Object { [System.Management.Automation.SemanticVersion]$_.version } | Sort-Object)[-1] # Validate that the version number has been updated. if ($currentProjectVersion -le $currentPublishedVersion) {