Skip to content

Commit 81d1916

Browse files
committed
add reusable workflow nuget-await-package-publishing.yml
1 parent ab64d84 commit 81d1916

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# SPDX-License-Identifier: MIT
2+
# SPDX-FileCopyrightText: "2025 smdn <[email protected]>"
3+
# cSpell:ignore pwsh
4+
5+
name: Wait for NuGet package publishing (reusable workflow)
6+
run-name: Wait for NuGet package publishing for ${{ inputs.release_tag }}
7+
8+
permissions: {}
9+
10+
on:
11+
workflow_call:
12+
inputs:
13+
release_tag:
14+
description: "The name of the tag for the release."
15+
required: true
16+
type: string
17+
18+
release_tag_prefix:
19+
description: "The common prefix of the release tag name."
20+
required: false
21+
type: string
22+
default: "releases/"
23+
24+
timeout_minutes:
25+
description: "The timeout minutes for waiting for package publishing."
26+
required: false
27+
type: number
28+
default: 15
29+
30+
update_interval_seconds:
31+
description: "The interval for retrieving package status, in seconds."
32+
required: false
33+
type: number
34+
default: 30
35+
36+
package_source:
37+
description: "The URL that is the base address for API requests for NuGet package information."
38+
required: false
39+
type: string
40+
default: "https://api.nuget.org/v3/index.json"
41+
42+
jobs:
43+
await-package-publishing:
44+
runs-on: ubuntu-latest
45+
timeout-minutes: ${{ fromJson(inputs.timeout_minutes) }}
46+
steps:
47+
- name: Determine the released package info
48+
id: released-package-info
49+
shell: pwsh
50+
run: |
51+
$release_tag = '${{ inputs.release_tag }}'
52+
53+
#
54+
# determine package ID and version
55+
#
56+
$pattern_release_tag = '^{0}{1}\-{2}$' -f
57+
'${{ inputs.release_tag_prefix }}',
58+
'(?<id>[A-Za-z0-9\.]+)',
59+
'(?<version>[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?([\-\+][0-9a-zA-Z\.]+)?)'
60+
61+
if ("$release_tag" -match "$pattern_release_tag") {
62+
# split package info and version from tag name
63+
$package_id = $Matches['id']
64+
$package_version = $Matches['version']
65+
66+
# notice determined info
67+
"::notice::package_id=${package_id}"
68+
"::notice::package_version=${package_version}"
69+
70+
# set outputs
71+
"package_id=${package_id}" >> $Env:GITHUB_OUTPUT
72+
"package_version=${package_version}" >> $Env:GITHUB_OUTPUT
73+
}
74+
else {
75+
"::error::The release tag name format mismatch: $release_tag"
76+
exit 1
77+
}
78+
79+
- name: Wait until the package is published
80+
shell: pwsh
81+
run: |
82+
# cSpell:disable-next-line
83+
# ref: smdn/Smdn.Fundamentals/src/Smdn.MSBuild.ProjectAssets.Common/project/scripts/psmodules/NuGet.ServiceIndex/NuGet.ServiceIndex.psm1
84+
function Get-NuGetResourceBaseAddress {
85+
[OutputType([string])]
86+
Param(
87+
[Parameter(Mandatory = $true)][string]$resource_type,
88+
[Parameter(Mandatory = $true)][string]$source_path
89+
)
90+
91+
$get_service_index_response = Invoke-WebRequest `
92+
-Method 'Get' `
93+
-SkipHttpErrorCheck `
94+
-URI $source_path
95+
96+
if ($get_service_index_response.StatusCode -ne 200) {
97+
$get_service_index_response | Write-Error
98+
throw "Failed to GET resource base address for ${resource_type} (StatusCode: $($get_service_index_response.StatusCode))"
99+
}
100+
101+
$service_index = $get_service_index_response.Content | ConvertFrom-Json
102+
103+
return $service_index.resources | `
104+
Where-Object '@type' -eq $resource_type | `
105+
Select-Object -ExpandProperty '@id'
106+
}
107+
108+
# based on smdn/Smdn.Fundamentals/src/Smdn.MSBuild.ProjectAssets.Common/project/scripts/QueryNuGetPackageReleased.ps1
109+
function Get-NuGetPackageManifestStatus {
110+
# [OutputType([Microsoft.PowerShell.Commands.BasicHtmlWebResponseObject])]
111+
Param(
112+
[Parameter(Mandatory = $true)][string]$package_source,
113+
[Parameter(Mandatory = $true)][string]$package_id,
114+
[Parameter(Mandatory = $true)][string]$package_version
115+
)
116+
117+
$nuget_service_package_base_address = Get-NuGetResourceBaseAddress 'PackageBaseAddress/3.0.0' $package_source
118+
119+
$package_id_lowercase = $package_id.ToLowerInvariant()
120+
121+
return Invoke-WebRequest `
122+
-Method 'Head' `
123+
-URI "${nuget_service_package_base_address}${package_id_lowercase}/${package_version}/${package_id_lowercase}.nuspec" `
124+
-SkipHttpErrorCheck `
125+
-TimeoutSec 20 `
126+
-ErrorAction Stop
127+
}
128+
129+
$package_source = '${{ inputs.package_source }}'
130+
$package_id = '${{ steps.released-package-info.outputs.package_id }}'
131+
$package_version = '${{ steps.released-package-info.outputs.package_version }}'
132+
133+
while ($true) {
134+
try {
135+
$resp = Get-NuGetPackageManifestStatus `
136+
$package_source `
137+
$package_id `
138+
$package_version
139+
140+
if ($resp.StatusCode -eq 200) {
141+
"::notice::📦 Package ${package_id}/${package_version} is now available in ${package_source}."
142+
break
143+
}
144+
else {
145+
"::warning::⚠️ $($resp.StatusCode) $($resp.StatusDescription) ${package_id}/${package_version}"
146+
}
147+
}
148+
catch {
149+
"::error::🚨 Unexpected error: $($_.Exception)"
150+
}
151+
152+
Start-Sleep -Seconds ${{ inputs.update_interval_seconds }}
153+
}

0 commit comments

Comments
 (0)