Skip to content

Commit aedec9b

Browse files
Copilotbaywet
andauthored
ci(release): share authenticated private-feed version checks
Co-authored-by: baywet <7905502+baywet@users.noreply.github.com>
1 parent c5b68c5 commit aedec9b

2 files changed

Lines changed: 95 additions & 65 deletions

File tree

‎.azure-pipelines/ci-build.yml‎

Lines changed: 34 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ variables:
2222
buildPlatform: 'Any CPU'
2323
buildConfiguration: 'Release'
2424
NuGetOrganizationName: 'openapinet'
25+
privateFeedBaseUrl: 'https://microsoftgraph.pkgs.visualstudio.com/0985d294-5762-4bc2-a565-161ef349ca3e/_packaging/GraphDeveloperExperiences_Public'
2526
ProductBinPath: '$(Build.SourcesDirectory)\src\Microsoft.OpenApi\bin\$(BuildConfiguration)'
2627
REGISTRY: 'msgraphprodregistry.azurecr.io'
2728
IMAGE_NAME: 'public/openapi/hidi'
@@ -89,7 +90,7 @@ extends:
8990
<configuration>
9091
<packageSources>
9192
<clear />
92-
<add key="GraphDeveloperExperiences_Public" value="https://microsoftgraph.pkgs.visualstudio.com/0985d294-5762-4bc2-a565-161ef349ca3e/_packaging/GraphDeveloperExperiences_Public/nuget/v3/index.json" />
93+
<add key="GraphDeveloperExperiences_Public" value="$(privateFeedBaseUrl)/nuget/v3/index.json" />
9394
</packageSources>
9495
</configuration>
9596
"@ | Set-Content -Path "$(Build.SourcesDirectory)/nuget.config" -Encoding UTF8
@@ -231,6 +232,13 @@ extends:
231232
*.nupkg
232233
*.snupkg
233234
235+
- task: CopyFiles@2
236+
displayName: 'Include version-check script in Nugets artifact'
237+
inputs:
238+
SourceFolder: '$(Build.SourcesDirectory)/scripts'
239+
Contents: 'checkNuGetVersion.ps1'
240+
TargetFolder: '$(Build.ArtifactStagingDirectory)/Nugets/scripts'
241+
234242
# Copy repository files to be used in the deploy stage
235243
- task: CopyFiles@2
236244
displayName: 'Copy repository files for deploy stage'
@@ -268,28 +276,15 @@ extends:
268276
pool:
269277
vmImage: ubuntu-latest
270278
steps:
271-
- pwsh: |
272-
$pkg = Get-ChildItem -Path "$(Pipeline.Workspace)" -Filter "Microsoft.OpenApi.Hidi.*.nupkg" | Where-Object { $_.Name -match '^Microsoft\.OpenApi\.Hidi\.(\d[\w\.\-]*)\.nupkg$' } | Select-Object -First 1
273-
if (-not $pkg) { throw "No Microsoft.OpenApi.Hidi nupkg found to publish." }
274-
$version = $pkg.Name -replace '^Microsoft\.OpenApi\.Hidi\.', '' -replace '\.nupkg$', ''
275-
$id = 'microsoft.openapi.hidi'
276-
$uri = "https://api.nuget.org/v3-flatcontainer/$id/index.json"
277-
try {
278-
$resp = Invoke-RestMethod -Uri $uri -Headers @{ 'User-Agent' = 'openapinet-azdo-pipeline' }
279-
if ($resp.versions -contains $version) {
280-
Write-Host "NuGet $id $version already published; skipping ESRP release (idempotent re-run)."
281-
Write-Host "##vso[task.setvariable variable=nugetAlreadyPublished]true"
282-
} else {
283-
Write-Host "NuGet $id $version not found on nuget.org; will publish via ESRP."
284-
Write-Host "##vso[task.setvariable variable=nugetAlreadyPublished]false"
285-
}
286-
} catch {
287-
if ($_.Exception.Response.StatusCode.value__ -eq 404) {
288-
Write-Host "NuGet $id has no published versions yet; will publish via ESRP."
289-
Write-Host "##vso[task.setvariable variable=nugetAlreadyPublished]false"
290-
} else { throw }
291-
}
279+
- task: PowerShell@2
292280
displayName: 'Check whether NuGet package version already published (idempotent)'
281+
inputs:
282+
targetType: filePath
283+
filePath: '$(Pipeline.Workspace)/scripts/checkNuGetVersion.ps1'
284+
arguments: '-PackageId "Microsoft.OpenApi.Hidi" -PackageDirectory "$(Pipeline.Workspace)" -NuGetServiceIndexUrl "$(privateFeedBaseUrl)/nuget/v3/index.json"'
285+
pwsh: true
286+
env:
287+
FEED_ACCESS_TOKEN: $(System.AccessToken)
293288
- task: CopyFiles@2
294289
displayName: 'Stage Hidi NuGet packages for ESRP release'
295290
condition: and(succeeded(), ne(variables['nugetAlreadyPublished'], 'true'))
@@ -339,28 +334,15 @@ extends:
339334
pool:
340335
vmImage: ubuntu-latest
341336
steps:
342-
- pwsh: |
343-
$pkg = Get-ChildItem -Path "$(Pipeline.Workspace)" -Filter "Microsoft.OpenApi.*.nupkg" | Where-Object { $_.Name -match '^Microsoft\.OpenApi\.(\d[\w\.\-]*)\.nupkg$' } | Select-Object -First 1
344-
if (-not $pkg) { throw "No Microsoft.OpenApi nupkg found to publish." }
345-
$version = $pkg.Name -replace '^Microsoft\.OpenApi\.', '' -replace '\.nupkg$', ''
346-
$id = 'microsoft.openapi'
347-
$uri = "https://api.nuget.org/v3-flatcontainer/$id/index.json"
348-
try {
349-
$resp = Invoke-RestMethod -Uri $uri -Headers @{ 'User-Agent' = 'openapinet-azdo-pipeline' }
350-
if ($resp.versions -contains $version) {
351-
Write-Host "NuGet $id $version already published; skipping ESRP release (idempotent re-run)."
352-
Write-Host "##vso[task.setvariable variable=nugetAlreadyPublished]true"
353-
} else {
354-
Write-Host "NuGet $id $version not found on nuget.org; will publish via ESRP."
355-
Write-Host "##vso[task.setvariable variable=nugetAlreadyPublished]false"
356-
}
357-
} catch {
358-
if ($_.Exception.Response.StatusCode.value__ -eq 404) {
359-
Write-Host "NuGet $id has no published versions yet; will publish via ESRP."
360-
Write-Host "##vso[task.setvariable variable=nugetAlreadyPublished]false"
361-
} else { throw }
362-
}
337+
- task: PowerShell@2
363338
displayName: 'Check whether NuGet package version already published (idempotent)'
339+
inputs:
340+
targetType: filePath
341+
filePath: '$(Pipeline.Workspace)/scripts/checkNuGetVersion.ps1'
342+
arguments: '-PackageId "Microsoft.OpenApi" -PackageDirectory "$(Pipeline.Workspace)" -NuGetServiceIndexUrl "$(privateFeedBaseUrl)/nuget/v3/index.json"'
343+
pwsh: true
344+
env:
345+
FEED_ACCESS_TOKEN: $(System.AccessToken)
364346
- task: CopyFiles@2
365347
displayName: 'Stage OpenAPI NuGet packages for ESRP release'
366348
condition: and(succeeded(), ne(variables['nugetAlreadyPublished'], 'true'))
@@ -412,28 +394,15 @@ extends:
412394
pool:
413395
vmImage: ubuntu-latest
414396
steps:
415-
- pwsh: |
416-
$pkg = Get-ChildItem -Path "$(Pipeline.Workspace)" -Filter "Microsoft.OpenApi.YamlReader.*.nupkg" | Where-Object { $_.Name -match '^Microsoft\.OpenApi\.YamlReader\.(\d[\w\.\-]*)\.nupkg$' } | Select-Object -First 1
417-
if (-not $pkg) { throw "No Microsoft.OpenApi.YamlReader nupkg found to publish." }
418-
$version = $pkg.Name -replace '^Microsoft\.OpenApi\.YamlReader\.', '' -replace '\.nupkg$', ''
419-
$id = 'microsoft.openapi.yamlreader'
420-
$uri = "https://api.nuget.org/v3-flatcontainer/$id/index.json"
421-
try {
422-
$resp = Invoke-RestMethod -Uri $uri -Headers @{ 'User-Agent' = 'openapinet-azdo-pipeline' }
423-
if ($resp.versions -contains $version) {
424-
Write-Host "NuGet $id $version already published; skipping ESRP release (idempotent re-run)."
425-
Write-Host "##vso[task.setvariable variable=nugetAlreadyPublished]true"
426-
} else {
427-
Write-Host "NuGet $id $version not found on nuget.org; will publish via ESRP."
428-
Write-Host "##vso[task.setvariable variable=nugetAlreadyPublished]false"
429-
}
430-
} catch {
431-
if ($_.Exception.Response.StatusCode.value__ -eq 404) {
432-
Write-Host "NuGet $id has no published versions yet; will publish via ESRP."
433-
Write-Host "##vso[task.setvariable variable=nugetAlreadyPublished]false"
434-
} else { throw }
435-
}
397+
- task: PowerShell@2
436398
displayName: 'Check whether NuGet package version already published (idempotent)'
399+
inputs:
400+
targetType: filePath
401+
filePath: '$(Pipeline.Workspace)/scripts/checkNuGetVersion.ps1'
402+
arguments: '-PackageId "Microsoft.OpenApi.YamlReader" -PackageDirectory "$(Pipeline.Workspace)" -NuGetServiceIndexUrl "$(privateFeedBaseUrl)/nuget/v3/index.json"'
403+
pwsh: true
404+
env:
405+
FEED_ACCESS_TOKEN: $(System.AccessToken)
437406
- task: CopyFiles@2
438407
displayName: 'Stage YAML reader NuGet packages for ESRP release'
439408
condition: and(succeeded(), ne(variables['nugetAlreadyPublished'], 'true'))
@@ -606,7 +575,7 @@ extends:
606575
<configuration>
607576
<packageSources>
608577
<clear />
609-
<add key="GraphDeveloperExperiences_Public" value="https://microsoftgraph.pkgs.visualstudio.com/0985d294-5762-4bc2-a565-161ef349ca3e/_packaging/GraphDeveloperExperiences_Public/nuget/v3/index.json" />
578+
<add key="GraphDeveloperExperiences_Public" value="$(privateFeedBaseUrl)/nuget/v3/index.json" />
610579
</packageSources>
611580
<packageSourceCredentials>
612581
<GraphDeveloperExperiences_Public>

‎scripts/checkNuGetVersion.ps1‎

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
param(
5+
[Parameter(Mandatory = $true)]
6+
[string]$PackageId,
7+
[Parameter(Mandatory = $true)]
8+
[string]$PackageDirectory,
9+
[Parameter(Mandatory = $true)]
10+
[string]$NuGetServiceIndexUrl
11+
)
12+
13+
$ErrorActionPreference = 'Stop'
14+
15+
if ([string]::IsNullOrWhiteSpace($env:FEED_ACCESS_TOKEN)) {
16+
throw 'No Azure Artifacts access token available for the version check.'
17+
}
18+
19+
$packagePattern = '^' + [regex]::Escape($PackageId) + '\.(\d[\w\.\-]*)\.nupkg$'
20+
$packages = @(Get-ChildItem -Path $PackageDirectory -Filter "$PackageId.*.nupkg" |
21+
Where-Object { $_.Name -match $packagePattern })
22+
if ($packages.Count -ne 1) {
23+
throw "Expected exactly one $PackageId nupkg to publish; found $($packages.Count)."
24+
}
25+
$version = [regex]::Match($packages[0].Name, $packagePattern, 'IgnoreCase').Groups[1].Value
26+
$id = $PackageId.ToLowerInvariant()
27+
$credentials = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("AzureDevOps:$($env:FEED_ACCESS_TOKEN)"))
28+
$headers = @{
29+
'User-Agent' = 'openapinet-azdo-pipeline'
30+
'Authorization' = "Basic $credentials"
31+
}
32+
33+
$serviceIndex = Invoke-RestMethod -Uri $NuGetServiceIndexUrl -Headers $headers
34+
$packageBaseAddress = $serviceIndex.resources |
35+
Where-Object { $_.'@type' -eq 'PackageBaseAddress/3.0.0' } |
36+
Select-Object -First 1 -ExpandProperty '@id'
37+
if ([string]::IsNullOrWhiteSpace($packageBaseAddress)) {
38+
throw 'The private NuGet feed does not advertise a package base address.'
39+
}
40+
41+
$uri = "$($packageBaseAddress.TrimEnd('/'))/$id/index.json"
42+
try {
43+
$response = Invoke-RestMethod -Uri $uri -Headers $headers
44+
if ($null -eq $response.versions) {
45+
throw 'The private NuGet feed returned an invalid package version response.'
46+
}
47+
$alreadyPublished = $response.versions -contains $version
48+
} catch {
49+
if ([int]$_.Exception.Response.StatusCode -eq 404) {
50+
$alreadyPublished = $false
51+
} else {
52+
throw
53+
}
54+
}
55+
56+
if ($alreadyPublished) {
57+
Write-Host "NuGet $id $version already present in the private feed; skipping ESRP release (idempotent re-run)."
58+
} else {
59+
Write-Host "NuGet $id $version not found in the private feed; will publish via ESRP."
60+
}
61+
Write-Host "##vso[task.setvariable variable=nugetAlreadyPublished]$($alreadyPublished.ToString().ToLowerInvariant())"

0 commit comments

Comments
 (0)