Skip to content

Commit f256dd6

Browse files
Normalize the releases JSON in a dedicated conversion function
Write-Output -NoEnumerate handed the caller an array nested inside an array, so the tag name of every release was concatenated into one string and rejected as an invalid SemVer. The JSON conversion now lives in its own function that always yields a flat array, including when the gh command produced no output at all. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 4ccb54f commit f256dd6

2 files changed

Lines changed: 85 additions & 6 deletions

File tree

.github/actions/Resolve-PSModuleVersion/src/Resolve-PSModuleVersion.Helpers.psm1

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -277,20 +277,52 @@ function Resolve-ReleaseDecision {
277277
}
278278
}
279279

280+
function ConvertFrom-GitHubReleaseJson {
281+
<#
282+
.SYNOPSIS
283+
Converts the JSON output of 'gh release list' into a flat array of release objects.
284+
285+
.DESCRIPTION
286+
Normalizes the release listing so a repository with no releases, or a command that
287+
produced no output at all, yields an empty array instead of $null.
288+
289+
.OUTPUTS
290+
Array of release objects. Empty when there are no releases.
291+
292+
.EXAMPLE
293+
$releases = ConvertFrom-GitHubReleaseJson -Json '[{"tagName":"v1.0.0"}]'
294+
#>
295+
[CmdletBinding()]
296+
[OutputType([object[]], [array])]
297+
param(
298+
# The raw JSON returned by 'gh release list'. Empty or null when the command produced no output.
299+
[Parameter()]
300+
[AllowNull()]
301+
[AllowEmptyString()]
302+
[string] $Json
303+
)
304+
305+
if ([string]::IsNullOrWhiteSpace($Json)) {
306+
return @()
307+
}
308+
309+
@($Json | ConvertFrom-Json)
310+
}
311+
280312
function Get-GitHubRelease {
281313
<#
282314
.SYNOPSIS
283315
Retrieves all releases from the current GitHub repository.
284316
285317
.DESCRIPTION
286318
Lists the releases of the current repository. A repository that has no releases yet
287-
returns an empty array rather than $null, so callers can treat the result uniformly.
319+
produces no output, so callers normalize the result with @() before using it.
288320
289321
.OUTPUTS
290-
Array of release objects. Empty when the repository has no releases.
322+
Array of release objects. Nothing when the repository has no releases.
291323
292324
.EXAMPLE
293-
$releases = Get-GitHubRelease
325+
$releases = @(Get-GitHubRelease)
294326
#>
295327
[CmdletBinding()]
296328
[OutputType([array])]
@@ -302,16 +334,15 @@ function Get-GitHubRelease {
302334
Write-Error 'Failed to list releases for the repo.'
303335
exit $LASTEXITCODE
304336
}
305-
$releases = @($releasesJson | ConvertFrom-Json)
337+
$releases = ConvertFrom-GitHubReleaseJson -Json $releasesJson
306338

307339
Write-Host '-------------------------------------------------'
308340
Write-Host "Found [$($releases.Count)] releases."
309341
Write-Host ($releases | Select-Object -Property name, isPrerelease, isLatest, publishedAt |
310342
Format-Table | Out-String)
311343
Write-Host '-------------------------------------------------'
312344

313-
# -NoEnumerate keeps an empty or single-element result an array through the pipeline.
314-
Write-Output -NoEnumerate -InputObject $releases
345+
$releases
315346
}
316347
}
317348

.github/actions/Resolve-PSModuleVersion/tests/Resolve-PSModuleVersion.Helpers.Tests.ps1

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,54 @@ BeforeAll {
9191
}
9292

9393
Describe 'Resolve-PSModuleVersion' {
94+
Describe 'ConvertFrom-GitHubReleaseJson' {
95+
Context 'ConvertFrom-GitHubReleaseJson - repository without releases' {
96+
It 'ConvertFrom-GitHubReleaseJson - returns an empty array for an empty JSON array' {
97+
$result = ConvertFrom-GitHubReleaseJson -Json '[]'
98+
@($result).Count | Should -Be 0
99+
}
100+
101+
It 'ConvertFrom-GitHubReleaseJson - returns an empty array when the command produced no output' {
102+
$result = ConvertFrom-GitHubReleaseJson -Json ''
103+
@($result).Count | Should -Be 0
104+
}
105+
106+
It 'ConvertFrom-GitHubReleaseJson - returns an empty array for null input' {
107+
$result = ConvertFrom-GitHubReleaseJson -Json $null
108+
@($result).Count | Should -Be 0
109+
}
110+
}
111+
112+
Context 'ConvertFrom-GitHubReleaseJson - releases present' {
113+
It 'ConvertFrom-GitHubReleaseJson - returns a flat array of release objects' {
114+
$json = '[{"tagName":"v1.2.3","isLatest":true},{"tagName":"v1.2.2","isLatest":false}]'
115+
$result = @(ConvertFrom-GitHubReleaseJson -Json $json)
116+
$result.Count | Should -Be 2
117+
$result[0].tagName | Should -Be 'v1.2.3'
118+
}
119+
120+
It 'ConvertFrom-GitHubReleaseJson - returns a single release without nesting it in an inner array' {
121+
$result = @(ConvertFrom-GitHubReleaseJson -Json '[{"tagName":"v0.0.1","isLatest":true}]')
122+
$result.Count | Should -Be 1
123+
$result[0].tagName | Should -Be 'v0.0.1'
124+
}
125+
126+
It 'ConvertFrom-GitHubReleaseJson - output binds to the Releases parameter without nesting' {
127+
$json = '[{"tagName":"v1.2.3","isLatest":true},{"tagName":"v1.2.2","isLatest":false}]'
128+
$releases = @(ConvertFrom-GitHubReleaseJson -Json $json)
129+
$result = Get-LatestGitHubVersion -Releases $releases
130+
$result.ToString() | Should -Be 'v1.2.3'
131+
}
132+
133+
It 'ConvertFrom-GitHubReleaseJson - survives the log group wrapper without nesting' {
134+
$json = '[{"tagName":"v1.2.3","isLatest":true},{"tagName":"v1.2.2","isLatest":false}]'
135+
$releases = @(LogGroup 'Get releases - GitHub' { ConvertFrom-GitHubReleaseJson -Json $json })
136+
$releases.Count | Should -Be 2
137+
$releases[0].tagName | Should -Be 'v1.2.3'
138+
}
139+
}
140+
}
141+
94142
Describe 'Get-LatestGitHubVersion' {
95143
Context 'Get-LatestGitHubVersion - repository without releases' {
96144
It 'Get-LatestGitHubVersion - returns 0.0.0 when the releases list is null' {

0 commit comments

Comments
 (0)