From d4480f968233a715aaae320f3af28adbd012da25 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 19:53:35 +0200 Subject: [PATCH 01/19] feat: always emit version regardless of publish decision Refactor main.ps1 to always resolve the latest published version and compute a next version. When ShouldPublish is false, a development prerelease version (patch bump + branch name) is produced via the new Get-DevVersion helper function. This ensures Version and FullVersion outputs are never empty, enabling downstream Build-Module to stamp a valid version into the manifest for every CI run. Fixes PSModule/Process-PSModule#348 --- scripts/Helpers.psm1 | 93 +++++++++++++++-- scripts/main.ps1 | 12 +-- tests/Helpers.Tests.ps1 | 216 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 304 insertions(+), 17 deletions(-) create mode 100644 tests/Helpers.Tests.ps1 diff --git a/scripts/Helpers.psm1 b/scripts/Helpers.psm1 index cb3eb8a..8cff4c1 100644 --- a/scripts/Helpers.psm1 +++ b/scripts/Helpers.psm1 @@ -586,6 +586,83 @@ function Get-NextModuleVersion { } } +function Get-DevVersion { + <# + .SYNOPSIS + Calculates a development prerelease version for non-publishable builds. + + .DESCRIPTION + When no release will be created, produces a patch-bumped prerelease version + using the branch name as the prerelease identifier. This ensures every build + receives a valid, unique version even when no publish will occur. + + .OUTPUTS + PSSemVer representing the development version. + + .EXAMPLE + $devVersion = Get-DevVersion -LatestVersion $latestVersion -Decision $decision ` + -Configuration $config -ModuleName 'MyModule' -Releases $releases +#> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', + Justification = 'Parameter is used inside LogGroup script block.')] + [CmdletBinding()] + [OutputType([object])] + param( + # The current latest published version. + [Parameter(Mandatory)] + [object] $LatestVersion, + + # The release decision object. + [Parameter(Mandatory)] + [PSCustomObject] $Decision, + + # The publish configuration object. + [Parameter(Mandatory)] + [PSCustomObject] $Configuration, + + # The name of the module. + [Parameter(Mandatory)] + [ValidateNotNullOrEmpty()] + [string] $ModuleName, + + # The GitHub releases list, used for incremental prerelease calculation. + [Parameter(Mandatory)] + [array] $Releases + ) + + LogGroup 'Calculate development version' { + $newVersion = New-PSSemVer -Version $LatestVersion + $newVersion.Prefix = $Configuration.VersionPrefix + + Write-Host 'No publish required. Generating development prerelease version.' + Write-Host 'Incrementing patch version.' + $newVersion.BumpPatch() + + $prereleaseName = $Decision.PrereleaseName + Write-Host "Adding prerelease tag using branch name [$prereleaseName]." + $newVersion.Prerelease = $prereleaseName + + if (-not [string]::IsNullOrEmpty($Configuration.DatePrereleaseFormat)) { + Write-Host "Using date-based prerelease format: [$($Configuration.DatePrereleaseFormat)]." + $newVersion.Prerelease += "$(Get-Date -Format $Configuration.DatePrereleaseFormat)" + } + + if ($Configuration.IncrementalPrerelease) { + $baseVersionString = "$($newVersion.Major).$($newVersion.Minor).$($newVersion.Patch)" + $params = @{ + ModuleName = $ModuleName + BaseVersion = $baseVersionString + PrereleaseName = $prereleaseName + Releases = $Releases + } + $newVersion.Prerelease += Get-NextPrereleaseNumber @params + } + + Write-Host "Development version: [$($newVersion.ToString())]" + $newVersion + } +} + function Write-ActionOutput { <# .SYNOPSIS @@ -602,21 +679,15 @@ function Write-ActionOutput { [Parameter(Mandatory)] [PSCustomObject] $Decision, - # The resolved next version, or $null when no release will be created. - [Parameter()] + # The resolved next version. + [Parameter(Mandatory)] [object] $NewVersion ) LogGroup 'Emit outputs' { - $versionString = '' - $prereleaseString = '' - $fullVersionString = '' - - if ($NewVersion) { - $versionString = "$($NewVersion.Major).$($NewVersion.Minor).$($NewVersion.Patch)" - $prereleaseString = [string]$NewVersion.Prerelease - $fullVersionString = $NewVersion.ToString() - } + $versionString = "$($NewVersion.Major).$($NewVersion.Minor).$($NewVersion.Patch)" + $prereleaseString = [string]$NewVersion.Prerelease + $fullVersionString = $NewVersion.ToString() $resolvedReleaseType = if ($Decision.ShouldPublish) { if ($Decision.CreateRelease) { 'Release' } else { 'Prerelease' } diff --git a/scripts/main.ps1 b/scripts/main.ps1 index 73f6d36..648b518 100644 --- a/scripts/main.ps1 +++ b/scripts/main.ps1 @@ -11,14 +11,12 @@ $config = Get-PublishConfiguration -SettingsJson $actionInput.SettingsJson $pullRequest = Get-GitHubPullRequest $decision = Resolve-ReleaseDecision -Configuration $config -PullRequest $pullRequest -$newVersion = $null +$releases = Get-GitHubRelease +$ghVersion = Get-LatestGitHubVersion -Releases $releases +$psGalleryVersion = Get-LatestPSGalleryVersion -ModuleName $actionInput.Name +$latestVersion = Get-LatestPublishedVersion -GitHubVersion $ghVersion -PSGalleryVersion $psGalleryVersion if ($decision.ShouldPublish) { - $releases = Get-GitHubRelease - $ghVersion = Get-LatestGitHubVersion -Releases $releases - $psGalleryVersion = Get-LatestPSGalleryVersion -ModuleName $actionInput.Name - $latestVersion = Get-LatestPublishedVersion -GitHubVersion $ghVersion -PSGalleryVersion $psGalleryVersion - $params = @{ LatestVersion = $latestVersion Decision = $decision @@ -27,6 +25,8 @@ if ($decision.ShouldPublish) { Releases = $releases } $newVersion = Get-NextModuleVersion @params +} else { + $newVersion = Get-DevVersion -LatestVersion $latestVersion -Decision $decision -Configuration $config -ModuleName $actionInput.Name -Releases $releases } Write-ActionOutput -Decision $decision -NewVersion $newVersion diff --git a/tests/Helpers.Tests.ps1 b/tests/Helpers.Tests.ps1 new file mode 100644 index 0000000..f0d92f1 --- /dev/null +++ b/tests/Helpers.Tests.ps1 @@ -0,0 +1,216 @@ +#Requires -Modules @{ ModuleName = 'Pester'; ModuleVersion = '5.0' } + +BeforeAll { + # Install PSSemVer for version handling + if (-not (Get-Module -ListAvailable -Name PSSemVer)) { + Install-PSResource -Name PSSemVer -Repository PSGallery -TrustRepository -Scope CurrentUser + } + Import-Module -Name PSSemVer -Force + + # Mock the Helpers module (LogGroup, Add-Content for GITHUB_OUTPUT) + function LogGroup { + param([string]$Name, [scriptblock]$ScriptBlock) + & $ScriptBlock + } + + # Import the module under test + Import-Module -Name "$PSScriptRoot/../scripts/Helpers.psm1" -Force +} + +Describe 'Get-DevVersion' { + BeforeAll { + $baseConfig = [PSCustomObject]@{ + AutoPatching = $false + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + VersionPrefix = 'v' + ReleaseType = 'None' + IgnoreLabels = @() + MajorLabels = @('Major') + MinorLabels = @('Minor') + PatchLabels = @('Patch') + } + # Use a placeholder release so the mandatory [array] parameter binds + $emptyReleases = @([PSCustomObject]@{ tagName = 'v0.0.0'; isLatest = $false; isPrerelease = $false }) + } + + It 'Emits a version when ReleaseType is None' { + $decision = [PSCustomObject]@{ + ShouldPublish = $false + CreateRelease = $false + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $false + PatchRelease = $false + HasVersionBump = $false + PrereleaseName = 'featurebranch' + } + $latestVersion = New-PSSemVer -Version '1.2.3' + + $result = Get-DevVersion -LatestVersion $latestVersion -Decision $decision ` + -Configuration $baseConfig -ModuleName 'TestModule' -Releases $emptyReleases + + $result | Should -Not -BeNullOrEmpty + "$($result.Major).$($result.Minor).$($result.Patch)" | Should -Be '1.2.4' + $result.Prerelease | Should -Be 'featurebranch' + } + + It 'Emits a version when ignore label is present' { + $decision = [PSCustomObject]@{ + ShouldPublish = $false + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $false + PatchRelease = $false + HasVersionBump = $false + PrereleaseName = 'mybranch' + } + $latestVersion = New-PSSemVer -Version '2.0.0' + + $result = Get-DevVersion -LatestVersion $latestVersion -Decision $decision ` + -Configuration $baseConfig -ModuleName 'TestModule' -Releases $emptyReleases + + $result | Should -Not -BeNullOrEmpty + "$($result.Major).$($result.Minor).$($result.Patch)" | Should -Be '2.0.1' + $result.Prerelease | Should -Be 'mybranch' + } + + It 'Emits a version when no version bump label and AutoPatching is false' { + $decision = [PSCustomObject]@{ + ShouldPublish = $false + CreateRelease = $false + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $false + PatchRelease = $false + HasVersionBump = $false + PrereleaseName = 'fixsomething' + } + $latestVersion = New-PSSemVer -Version '0.0.0' + + $result = Get-DevVersion -LatestVersion $latestVersion -Decision $decision ` + -Configuration $baseConfig -ModuleName 'TestModule' -Releases $emptyReleases + + $result | Should -Not -BeNullOrEmpty + "$($result.Major).$($result.Minor).$($result.Patch)" | Should -Be '0.0.1' + $result.Prerelease | Should -Be 'fixsomething' + } + + It 'Applies version prefix from configuration' { + $decision = [PSCustomObject]@{ + ShouldPublish = $false + CreateRelease = $false + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $false + PatchRelease = $false + HasVersionBump = $false + PrereleaseName = 'dev' + } + $latestVersion = New-PSSemVer -Version '1.0.0' + + $result = Get-DevVersion -LatestVersion $latestVersion -Decision $decision ` + -Configuration $baseConfig -ModuleName 'TestModule' -Releases $emptyReleases + + $result.Prefix | Should -Be 'v' + $result.ToString() | Should -BeLike 'v1.0.1-dev*' + } +} + +Describe 'Get-NextModuleVersion - existing behavior unchanged' { + BeforeAll { + $emptyReleases = @([PSCustomObject]@{ tagName = 'v0.0.0'; isLatest = $false; isPrerelease = $false }) + } + + It 'Correctly bumps major version' { + $decision = [PSCustomObject]@{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $true + MinorRelease = $false + PatchRelease = $false + HasVersionBump = $true + PrereleaseName = 'main' + } + $config = [PSCustomObject]@{ + AutoPatching = $false + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + VersionPrefix = '' + ReleaseType = 'Release' + IgnoreLabels = @() + MajorLabels = @('Major') + MinorLabels = @('Minor') + PatchLabels = @('Patch') + } + $latestVersion = New-PSSemVer -Version '1.2.3' + + $result = Get-NextModuleVersion -LatestVersion $latestVersion -Decision $decision ` + -Configuration $config -ModuleName 'TestModule' -Releases $emptyReleases + + "$($result.Major).$($result.Minor).$($result.Patch)" | Should -Be '2.0.0' + $result.Prerelease | Should -BeNullOrEmpty + } + + It 'Correctly bumps minor version' { + $decision = [PSCustomObject]@{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $true + PatchRelease = $false + HasVersionBump = $true + PrereleaseName = 'main' + } + $config = [PSCustomObject]@{ + AutoPatching = $false + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + VersionPrefix = '' + ReleaseType = 'Release' + IgnoreLabels = @() + MajorLabels = @('Major') + MinorLabels = @('Minor') + PatchLabels = @('Patch') + } + $latestVersion = New-PSSemVer -Version '1.2.3' + + $result = Get-NextModuleVersion -LatestVersion $latestVersion -Decision $decision ` + -Configuration $config -ModuleName 'TestModule' -Releases $emptyReleases + + "$($result.Major).$($result.Minor).$($result.Patch)" | Should -Be '1.3.0' + } + + It 'Correctly bumps patch version' { + $decision = [PSCustomObject]@{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'main' + } + $config = [PSCustomObject]@{ + AutoPatching = $false + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + VersionPrefix = '' + ReleaseType = 'Release' + IgnoreLabels = @() + MajorLabels = @('Major') + MinorLabels = @('Minor') + PatchLabels = @('Patch') + } + $latestVersion = New-PSSemVer -Version '1.2.3' + + $result = Get-NextModuleVersion -LatestVersion $latestVersion -Decision $decision ` + -Configuration $config -ModuleName 'TestModule' -Releases $emptyReleases + + "$($result.Major).$($result.Minor).$($result.Patch)" | Should -Be '1.2.4' + } +} From ac4f7b1e1e26e4a73f62519a602b9ffd95b05c45 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 20:33:16 +0200 Subject: [PATCH 02/19] fix: correct formatting of documentation comments in helper functions --- scripts/Helpers.psm1 | 234 +++++++++++++++++++++---------------------- 1 file changed, 117 insertions(+), 117 deletions(-) diff --git a/scripts/Helpers.psm1 b/scripts/Helpers.psm1 index 8cff4c1..6647136 100644 --- a/scripts/Helpers.psm1 +++ b/scripts/Helpers.psm1 @@ -1,13 +1,13 @@ function Split-CommaSeparatedList { <# - .SYNOPSIS - Splits a comma-separated string into a trimmed, non-empty array. + .SYNOPSIS + Splits a comma-separated string into a trimmed, non-empty array. - .EXAMPLE - Split-CommaSeparatedList -Value 'Major, Minor, Patch' + .EXAMPLE + Split-CommaSeparatedList -Value 'Major, Minor, Patch' - Returns @('Major', 'Minor', 'Patch'). -#> + Returns @('Major', 'Minor', 'Patch'). + #> [CmdletBinding()] [OutputType([string[]])] param( @@ -21,19 +21,19 @@ function Read-ActionInput { <# - .SYNOPSIS - Reads and validates action inputs from environment variables. + .SYNOPSIS + Reads and validates action inputs from environment variables. - .DESCRIPTION - Reads the module name and settings JSON from GitHub Actions environment variables. - Falls back to the repository name when the module name input is not provided. + .DESCRIPTION + Reads the module name and settings JSON from GitHub Actions environment variables. + Falls back to the repository name when the module name input is not provided. - .OUTPUTS - PSCustomObject with Name and SettingsJson properties. + .OUTPUTS + PSCustomObject with Name and SettingsJson properties. - .EXAMPLE - $actionInput = Read-ActionInput -#> + .EXAMPLE + $actionInput = Read-ActionInput + #> [CmdletBinding()] [OutputType([PSCustomObject])] param() @@ -62,19 +62,19 @@ function Read-ActionInput { function Get-PublishConfiguration { <# - .SYNOPSIS - Parses the settings JSON into a publish configuration object. + .SYNOPSIS + Parses the settings JSON into a publish configuration object. - .DESCRIPTION - Extracts publish module settings including auto-patching flags, version prefix, - release type, and label classification arrays. + .DESCRIPTION + Extracts publish module settings including auto-patching flags, version prefix, + release type, and label classification arrays. - .OUTPUTS - PSCustomObject with publish configuration properties. + .OUTPUTS + PSCustomObject with publish configuration properties. - .EXAMPLE - $config = Get-PublishConfiguration -SettingsJson $actionInput.SettingsJson -#> + .EXAMPLE + $config = Get-PublishConfiguration -SettingsJson $actionInput.SettingsJson + #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Parameter is used inside LogGroup script block.')] [CmdletBinding()] @@ -122,19 +122,19 @@ function Get-PublishConfiguration { function Get-GitHubPullRequest { <# - .SYNOPSIS - Reads and validates the GitHub pull request from the event payload. + .SYNOPSIS + Reads and validates the GitHub pull request from the event payload. - .DESCRIPTION - Loads the GitHub event from the input override or from the event path file, - then validates and extracts pull request data. + .DESCRIPTION + Loads the GitHub event from the input override or from the event path file, + then validates and extracts pull request data. - .OUTPUTS - PSCustomObject with HeadRef and Labels properties. + .OUTPUTS + PSCustomObject with HeadRef and Labels properties. - .EXAMPLE - $pullRequest = Get-GitHubPullRequest -#> + .EXAMPLE + $pullRequest = Get-GitHubPullRequest + #> [CmdletBinding()] [OutputType([PSCustomObject])] param() @@ -171,20 +171,20 @@ function Get-GitHubPullRequest { function Resolve-ReleaseDecision { <# - .SYNOPSIS - Determines whether to publish a release and what kind of version bump to apply. + .SYNOPSIS + Determines whether to publish a release and what kind of version bump to apply. - .DESCRIPTION - Evaluates the PR labels against the configured label categories and release type - to produce a complete release decision. + .DESCRIPTION + Evaluates the PR labels against the configured label categories and release type + to produce a complete release decision. - .OUTPUTS - PSCustomObject with ShouldPublish, CreateRelease, CreatePrerelease, MajorRelease, - MinorRelease, PatchRelease, HasVersionBump, and PrereleaseName properties. + .OUTPUTS + PSCustomObject with ShouldPublish, CreateRelease, CreatePrerelease, MajorRelease, + MinorRelease, PatchRelease, HasVersionBump, and PrereleaseName properties. - .EXAMPLE - $decision = Resolve-ReleaseDecision -Configuration $config -PullRequest $pullRequest -#> + .EXAMPLE + $decision = Resolve-ReleaseDecision -Configuration $config -PullRequest $pullRequest + #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Parameter is used inside LogGroup script block.')] [CmdletBinding()] @@ -268,15 +268,15 @@ function Resolve-ReleaseDecision { function Get-GitHubRelease { <# - .SYNOPSIS - Retrieves all releases from the current GitHub repository. + .SYNOPSIS + Retrieves all releases from the current GitHub repository. - .OUTPUTS - Array of release objects. + .OUTPUTS + Array of release objects. - .EXAMPLE - $releases = Get-GitHubReleases -#> + .EXAMPLE + $releases = Get-GitHubReleases + #> [CmdletBinding()] [OutputType([array])] param() @@ -300,15 +300,15 @@ function Get-GitHubRelease { function Get-LatestGitHubVersion { <# - .SYNOPSIS - Extracts the latest stable version from a GitHub releases list. + .SYNOPSIS + Extracts the latest stable version from a GitHub releases list. - .OUTPUTS - PSSemVer representing the latest GitHub release version. + .OUTPUTS + PSSemVer representing the latest GitHub release version. - .EXAMPLE - $ghVersion = Get-LatestGitHubVersion -Releases $releases -#> + .EXAMPLE + $ghVersion = Get-LatestGitHubVersion -Releases $releases + #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Parameter is used inside LogGroup script block.')] [CmdletBinding()] @@ -337,19 +337,19 @@ function Get-LatestGitHubVersion { function Get-LatestPSGalleryVersion { <# - .SYNOPSIS - Finds the latest stable version of a module in the PowerShell Gallery. + .SYNOPSIS + Finds the latest stable version of a module in the PowerShell Gallery. - .DESCRIPTION - Queries the PowerShell Gallery for the latest published version of the module. - Retries up to five times with a ten-second delay between attempts. + .DESCRIPTION + Queries the PowerShell Gallery for the latest published version of the module. + Retries up to five times with a ten-second delay between attempts. - .OUTPUTS - PSSemVer representing the latest PSGallery version. + .OUTPUTS + PSSemVer representing the latest PSGallery version. - .EXAMPLE - $psGalleryVersion = Get-LatestPSGalleryVersion -ModuleName 'MyModule' -#> + .EXAMPLE + $psGalleryVersion = Get-LatestPSGalleryVersion -ModuleName 'MyModule' + #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Parameter is used inside LogGroup script block.')] [CmdletBinding()] @@ -395,15 +395,15 @@ function Get-LatestPSGalleryVersion { function Get-LatestPublishedVersion { <# - .SYNOPSIS - Returns the highest version between GitHub and the PowerShell Gallery. + .SYNOPSIS + Returns the highest version between GitHub and the PowerShell Gallery. - .OUTPUTS - PSSemVer representing the highest known published version. + .OUTPUTS + PSSemVer representing the highest known published version. - .EXAMPLE - $latestVersion = Get-LatestPublishedVersion -GitHubVersion $ghVersion -PSGalleryVersion $psGalleryVersion -#> + .EXAMPLE + $latestVersion = Get-LatestPublishedVersion -GitHubVersion $ghVersion -PSGalleryVersion $psGalleryVersion + #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Parameter is used inside LogGroup script block.')] [CmdletBinding()] @@ -429,20 +429,20 @@ function Get-LatestPublishedVersion { function Get-NextPrereleaseNumber { <# - .SYNOPSIS - Calculates the next incremental prerelease number across GitHub and PSGallery. + .SYNOPSIS + Calculates the next incremental prerelease number across GitHub and PSGallery. - .DESCRIPTION - Queries both GitHub releases and the PowerShell Gallery for existing prereleases - matching the base version and prerelease name, then returns the next number - zero-padded to three digits. + .DESCRIPTION + Queries both GitHub releases and the PowerShell Gallery for existing prereleases + matching the base version and prerelease name, then returns the next number + zero-padded to three digits. - .OUTPUTS - String. A zero-padded three-digit number (e.g. '001'). + .OUTPUTS + String. A zero-padded three-digit number (e.g. '001'). - .EXAMPLE - $number = Get-NextPrereleaseNumber -ModuleName 'MyModule' -BaseVersion '1.2.3' -PrereleaseName 'mybranch' -Releases $releases -#> + .EXAMPLE + $number = Get-NextPrereleaseNumber -ModuleName 'MyModule' -BaseVersion '1.2.3' -PrereleaseName 'mybranch' -Releases $releases + #> [CmdletBinding()] [OutputType([string])] param( @@ -502,20 +502,20 @@ function Get-NextPrereleaseNumber { function Get-NextModuleVersion { <# - .SYNOPSIS - Calculates the next module version based on the release decision. + .SYNOPSIS + Calculates the next module version based on the release decision. - .DESCRIPTION - Increments the current version according to the version bump type (major, minor, or patch), - then optionally appends a prerelease suffix with support for date-based and incremental numbering. + .DESCRIPTION + Increments the current version according to the version bump type (major, minor, or patch), + then optionally appends a prerelease suffix with support for date-based and incremental numbering. - .OUTPUTS - PSSemVer representing the resolved next version. + .OUTPUTS + PSSemVer representing the resolved next version. - .EXAMPLE - $newVersion = Get-NextModuleVersion -LatestVersion $latestVersion -Decision $decision ` - -Configuration $config -ModuleName 'MyModule' -Releases $releases -#> + .EXAMPLE + $newVersion = Get-NextModuleVersion -LatestVersion $latestVersion -Decision $decision ` + -Configuration $config -ModuleName 'MyModule' -Releases $releases + #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Parameter is used inside LogGroup script block.')] [CmdletBinding()] @@ -588,21 +588,21 @@ function Get-NextModuleVersion { function Get-DevVersion { <# - .SYNOPSIS - Calculates a development prerelease version for non-publishable builds. + .SYNOPSIS + Calculates a development prerelease version for non-publishable builds. - .DESCRIPTION - When no release will be created, produces a patch-bumped prerelease version - using the branch name as the prerelease identifier. This ensures every build - receives a valid, unique version even when no publish will occur. + .DESCRIPTION + When no release will be created, produces a patch-bumped prerelease version + using the branch name as the prerelease identifier. This ensures every build + receives a valid, unique version even when no publish will occur. - .OUTPUTS - PSSemVer representing the development version. + .OUTPUTS + PSSemVer representing the development version. - .EXAMPLE - $devVersion = Get-DevVersion -LatestVersion $latestVersion -Decision $decision ` - -Configuration $config -ModuleName 'MyModule' -Releases $releases -#> + .EXAMPLE + $devVersion = Get-DevVersion -LatestVersion $latestVersion -Decision $decision ` + -Configuration $config -ModuleName 'MyModule' -Releases $releases + #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Parameter is used inside LogGroup script block.')] [CmdletBinding()] @@ -665,12 +665,12 @@ function Get-DevVersion { function Write-ActionOutput { <# - .SYNOPSIS - Emits the resolved version and release type as GitHub Actions step outputs. + .SYNOPSIS + Emits the resolved version and release type as GitHub Actions step outputs. - .EXAMPLE - Write-ActionOutput -Decision $decision -NewVersion $newVersion -#> + .EXAMPLE + Write-ActionOutput -Decision $decision -NewVersion $newVersion + #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Parameter is used inside LogGroup script block.')] [CmdletBinding()] From 0888d1f9b70a24f2def260378757dfb615c5d9a3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 20:45:22 +0200 Subject: [PATCH 03/19] refactor: remove Get-DevVersion, reuse Get-NextModuleVersion with synthesized decision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Non-publishable builds now pass a synthesized prerelease decision (patch bump + prerelease flag) to the existing Get-NextModuleVersion function — no separate function needed. The original decision is preserved for Write-ActionOutput so CreateRelease stays false. --- scripts/Helpers.psm1 | 77 ----------------------------------------- scripts/main.ps1 | 31 +++++++++++------ tests/Helpers.Tests.ps1 | 50 +++++++++++++------------- 3 files changed, 46 insertions(+), 112 deletions(-) diff --git a/scripts/Helpers.psm1 b/scripts/Helpers.psm1 index 6647136..dcab779 100644 --- a/scripts/Helpers.psm1 +++ b/scripts/Helpers.psm1 @@ -586,83 +586,6 @@ function Get-NextModuleVersion { } } -function Get-DevVersion { - <# - .SYNOPSIS - Calculates a development prerelease version for non-publishable builds. - - .DESCRIPTION - When no release will be created, produces a patch-bumped prerelease version - using the branch name as the prerelease identifier. This ensures every build - receives a valid, unique version even when no publish will occur. - - .OUTPUTS - PSSemVer representing the development version. - - .EXAMPLE - $devVersion = Get-DevVersion -LatestVersion $latestVersion -Decision $decision ` - -Configuration $config -ModuleName 'MyModule' -Releases $releases - #> - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', - Justification = 'Parameter is used inside LogGroup script block.')] - [CmdletBinding()] - [OutputType([object])] - param( - # The current latest published version. - [Parameter(Mandatory)] - [object] $LatestVersion, - - # The release decision object. - [Parameter(Mandatory)] - [PSCustomObject] $Decision, - - # The publish configuration object. - [Parameter(Mandatory)] - [PSCustomObject] $Configuration, - - # The name of the module. - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] - [string] $ModuleName, - - # The GitHub releases list, used for incremental prerelease calculation. - [Parameter(Mandatory)] - [array] $Releases - ) - - LogGroup 'Calculate development version' { - $newVersion = New-PSSemVer -Version $LatestVersion - $newVersion.Prefix = $Configuration.VersionPrefix - - Write-Host 'No publish required. Generating development prerelease version.' - Write-Host 'Incrementing patch version.' - $newVersion.BumpPatch() - - $prereleaseName = $Decision.PrereleaseName - Write-Host "Adding prerelease tag using branch name [$prereleaseName]." - $newVersion.Prerelease = $prereleaseName - - if (-not [string]::IsNullOrEmpty($Configuration.DatePrereleaseFormat)) { - Write-Host "Using date-based prerelease format: [$($Configuration.DatePrereleaseFormat)]." - $newVersion.Prerelease += "$(Get-Date -Format $Configuration.DatePrereleaseFormat)" - } - - if ($Configuration.IncrementalPrerelease) { - $baseVersionString = "$($newVersion.Major).$($newVersion.Minor).$($newVersion.Patch)" - $params = @{ - ModuleName = $ModuleName - BaseVersion = $baseVersionString - PrereleaseName = $prereleaseName - Releases = $Releases - } - $newVersion.Prerelease += Get-NextPrereleaseNumber @params - } - - Write-Host "Development version: [$($newVersion.ToString())]" - $newVersion - } -} - function Write-ActionOutput { <# .SYNOPSIS diff --git a/scripts/main.ps1 b/scripts/main.ps1 index 648b518..bb4414e 100644 --- a/scripts/main.ps1 +++ b/scripts/main.ps1 @@ -16,17 +16,28 @@ $ghVersion = Get-LatestGitHubVersion -Releases $releases $psGalleryVersion = Get-LatestPSGalleryVersion -ModuleName $actionInput.Name $latestVersion = Get-LatestPublishedVersion -GitHubVersion $ghVersion -PSGalleryVersion $psGalleryVersion -if ($decision.ShouldPublish) { - $params = @{ - LatestVersion = $latestVersion - Decision = $decision - Configuration = $config - ModuleName = $actionInput.Name - Releases = $releases - } - $newVersion = Get-NextModuleVersion @params +$versionDecision = if ($decision.ShouldPublish) { + $decision } else { - $newVersion = Get-DevVersion -LatestVersion $latestVersion -Decision $decision -Configuration $config -ModuleName $actionInput.Name -Releases $releases + [PSCustomObject]@{ + ShouldPublish = $true + CreateRelease = $false + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = $decision.PrereleaseName + } +} + +$params = @{ + LatestVersion = $latestVersion + Decision = $versionDecision + Configuration = $config + ModuleName = $actionInput.Name + Releases = $releases } +$newVersion = Get-NextModuleVersion @params Write-ActionOutput -Decision $decision -NewVersion $newVersion diff --git a/tests/Helpers.Tests.ps1 b/tests/Helpers.Tests.ps1 index f0d92f1..6023f71 100644 --- a/tests/Helpers.Tests.ps1 +++ b/tests/Helpers.Tests.ps1 @@ -17,7 +17,7 @@ BeforeAll { Import-Module -Name "$PSScriptRoot/../scripts/Helpers.psm1" -Force } -Describe 'Get-DevVersion' { +Describe 'Non-publishable builds emit a prerelease version via Get-NextModuleVersion' { BeforeAll { $baseConfig = [PSCustomObject]@{ AutoPatching = $false @@ -34,20 +34,20 @@ Describe 'Get-DevVersion' { $emptyReleases = @([PSCustomObject]@{ tagName = 'v0.0.0'; isLatest = $false; isPrerelease = $false }) } - It 'Emits a version when ReleaseType is None' { + It 'Emits a version when ReleaseType is None (synthesized prerelease decision)' { $decision = [PSCustomObject]@{ - ShouldPublish = $false + ShouldPublish = $true CreateRelease = $false - CreatePrerelease = $false + CreatePrerelease = $true MajorRelease = $false MinorRelease = $false - PatchRelease = $false - HasVersionBump = $false + PatchRelease = $true + HasVersionBump = $true PrereleaseName = 'featurebranch' } $latestVersion = New-PSSemVer -Version '1.2.3' - $result = Get-DevVersion -LatestVersion $latestVersion -Decision $decision ` + $result = Get-NextModuleVersion -LatestVersion $latestVersion -Decision $decision ` -Configuration $baseConfig -ModuleName 'TestModule' -Releases $emptyReleases $result | Should -Not -BeNullOrEmpty @@ -55,20 +55,20 @@ Describe 'Get-DevVersion' { $result.Prerelease | Should -Be 'featurebranch' } - It 'Emits a version when ignore label is present' { + It 'Emits a version when ignore label is present (synthesized prerelease decision)' { $decision = [PSCustomObject]@{ - ShouldPublish = $false - CreateRelease = $true - CreatePrerelease = $false + ShouldPublish = $true + CreateRelease = $false + CreatePrerelease = $true MajorRelease = $false MinorRelease = $false - PatchRelease = $false - HasVersionBump = $false + PatchRelease = $true + HasVersionBump = $true PrereleaseName = 'mybranch' } $latestVersion = New-PSSemVer -Version '2.0.0' - $result = Get-DevVersion -LatestVersion $latestVersion -Decision $decision ` + $result = Get-NextModuleVersion -LatestVersion $latestVersion -Decision $decision ` -Configuration $baseConfig -ModuleName 'TestModule' -Releases $emptyReleases $result | Should -Not -BeNullOrEmpty @@ -76,20 +76,20 @@ Describe 'Get-DevVersion' { $result.Prerelease | Should -Be 'mybranch' } - It 'Emits a version when no version bump label and AutoPatching is false' { + It 'Emits a version when no version bump label and AutoPatching is false (synthesized prerelease decision)' { $decision = [PSCustomObject]@{ - ShouldPublish = $false + ShouldPublish = $true CreateRelease = $false - CreatePrerelease = $false + CreatePrerelease = $true MajorRelease = $false MinorRelease = $false - PatchRelease = $false - HasVersionBump = $false + PatchRelease = $true + HasVersionBump = $true PrereleaseName = 'fixsomething' } $latestVersion = New-PSSemVer -Version '0.0.0' - $result = Get-DevVersion -LatestVersion $latestVersion -Decision $decision ` + $result = Get-NextModuleVersion -LatestVersion $latestVersion -Decision $decision ` -Configuration $baseConfig -ModuleName 'TestModule' -Releases $emptyReleases $result | Should -Not -BeNullOrEmpty @@ -99,18 +99,18 @@ Describe 'Get-DevVersion' { It 'Applies version prefix from configuration' { $decision = [PSCustomObject]@{ - ShouldPublish = $false + ShouldPublish = $true CreateRelease = $false - CreatePrerelease = $false + CreatePrerelease = $true MajorRelease = $false MinorRelease = $false - PatchRelease = $false - HasVersionBump = $false + PatchRelease = $true + HasVersionBump = $true PrereleaseName = 'dev' } $latestVersion = New-PSSemVer -Version '1.0.0' - $result = Get-DevVersion -LatestVersion $latestVersion -Decision $decision ` + $result = Get-NextModuleVersion -LatestVersion $latestVersion -Decision $decision ` -Configuration $baseConfig -ModuleName 'TestModule' -Releases $emptyReleases $result.Prefix | Should -Be 'v' From eec8d46ff2604691eeb6e2a4b0036e874aea6794 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 20:48:50 +0200 Subject: [PATCH 04/19] refactor: move prerelease fallback into Resolve-ReleaseDecision When ShouldPublish is false, Resolve-ReleaseDecision now defaults to CreatePrerelease + PatchRelease so Get-NextModuleVersion always has a valid bump. This removes the synthesized decision from main.ps1 and keeps version strategy logic in one place. --- scripts/Helpers.psm1 | 8 ++++++++ scripts/main.ps1 | 17 +---------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/scripts/Helpers.psm1 b/scripts/Helpers.psm1 index dcab779..bb494e5 100644 --- a/scripts/Helpers.psm1 +++ b/scripts/Helpers.psm1 @@ -241,6 +241,14 @@ function Resolve-ReleaseDecision { } } + # When no publish will occur, default to a prerelease patch so a version is always produced. + if (-not $shouldPublish) { + Write-Host 'Defaulting to prerelease patch for development version.' + $createPrerelease = $true + $patchRelease = $true + $hasVersionBump = $true + } + Write-Host '-------------------------------------------------' Write-Host ([PSCustomObject]@{ ReleaseType = $releaseType diff --git a/scripts/main.ps1 b/scripts/main.ps1 index bb4414e..b22dd6a 100644 --- a/scripts/main.ps1 +++ b/scripts/main.ps1 @@ -16,24 +16,9 @@ $ghVersion = Get-LatestGitHubVersion -Releases $releases $psGalleryVersion = Get-LatestPSGalleryVersion -ModuleName $actionInput.Name $latestVersion = Get-LatestPublishedVersion -GitHubVersion $ghVersion -PSGalleryVersion $psGalleryVersion -$versionDecision = if ($decision.ShouldPublish) { - $decision -} else { - [PSCustomObject]@{ - ShouldPublish = $true - CreateRelease = $false - CreatePrerelease = $true - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = $decision.PrereleaseName - } -} - $params = @{ LatestVersion = $latestVersion - Decision = $versionDecision + Decision = $decision Configuration = $config ModuleName = $actionInput.Name Releases = $releases From 42c7d3feb67363060e9e44263546eed02305ce46 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 21:00:54 +0200 Subject: [PATCH 05/19] feat: ensure a prerelease patch version is always produced in Resolve-ReleaseDecision --- scripts/Helpers.psm1 | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/scripts/Helpers.psm1 b/scripts/Helpers.psm1 index bb494e5..5e97f90 100644 --- a/scripts/Helpers.psm1 +++ b/scripts/Helpers.psm1 @@ -222,10 +222,14 @@ function Resolve-ReleaseDecision { $shouldPublish = $false } + # Defaults: always produce a prerelease patch version. $majorRelease = $false $minorRelease = $false - $patchRelease = $false - $hasVersionBump = $false + $patchRelease = $true + $hasVersionBump = $true + if (-not $shouldPublish) { + $createPrerelease = $true + } if ($shouldPublish) { $majorRelease = ($labels | Where-Object { $Configuration.MajorLabels -contains $_ }).Count -gt 0 @@ -238,17 +242,12 @@ function Resolve-ReleaseDecision { if (-not $hasVersionBump) { Write-Host 'No version bump label found and AutoPatching is disabled. No release will be created.' $shouldPublish = $false + $createPrerelease = $true + $patchRelease = $true + $hasVersionBump = $true } } - # When no publish will occur, default to a prerelease patch so a version is always produced. - if (-not $shouldPublish) { - Write-Host 'Defaulting to prerelease patch for development version.' - $createPrerelease = $true - $patchRelease = $true - $hasVersionBump = $true - } - Write-Host '-------------------------------------------------' Write-Host ([PSCustomObject]@{ ReleaseType = $releaseType From 81104866f3cd0d5d350277fc9cc276124eacf4ae Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 21:04:32 +0200 Subject: [PATCH 06/19] fix: add GH_TOKEN env var for gh CLI authentication --- action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/action.yml b/action.yml index c2843ea..6d5c6bf 100644 --- a/action.yml +++ b/action.yml @@ -66,6 +66,7 @@ runs: shell: pwsh working-directory: ${{ inputs.WorkingDirectory }} env: + GH_TOKEN: ${{ github.token }} PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_Settings: ${{ inputs.Settings }} PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_Name: ${{ inputs.Name }} PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_EventJson: ${{ inputs.EventJson }} From 9d8dc692dffe9815e62f26c9fa185706acbbf1d3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 21:05:13 +0200 Subject: [PATCH 07/19] fix: remove GH_TOKEN environment variable from Resolve-PSModuleVersion step --- .github/workflows/Action-Test.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index 3df83f7..f423238 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -43,8 +43,6 @@ jobs: - name: Resolve-PSModuleVersion id: resolve uses: ./ - env: - GH_TOKEN: ${{ github.token }} with: Settings: | { From 9be29fbaa494e07771df15eba5d5c3814fd321b2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 21:09:27 +0200 Subject: [PATCH 08/19] test: update None release type expectations to verify emitted version --- .github/workflows/Action-Test.yml | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index f423238..3085430 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -511,12 +511,23 @@ jobs: - name: Verify - None release type shell: pwsh env: + GH_TOKEN: ${{ github.token }} RESOLVE_CREATE_RELEASE: ${{ steps.resolve.outputs.CreateRelease }} RESOLVE_VERSION: ${{ steps.resolve.outputs.Version }} + RESOLVE_PRERELEASE: ${{ steps.resolve.outputs.Prerelease }} RESOLVE_RELEASE_TYPE: ${{ steps.resolve.outputs.ReleaseType }} + RESOLVE_FULL_VERSION: ${{ steps.resolve.outputs.FullVersion }} run: | $PSStyle.OutputRendering = 'Ansi' + $releases = (gh release list --json 'tagName,isLatest') | ConvertFrom-Json + $latestTag = ($releases | Where-Object { $_.isLatest }).tagName + if ([string]::IsNullOrEmpty($latestTag)) { $parts = @(0, 0, 0) } + else { $parts = ($latestTag -replace '^v', '').Split('.') | ForEach-Object { [int]$_ } } + $expectedVersion = "$($parts[0]).$($parts[1]).$($parts[2] + 1)" + $expectedPrerelease = 'feattestnone001' + $expectedFullVersion = "v$expectedVersion-$expectedPrerelease" + Write-Host '--- Input ---' Write-Host "EventJson: {`"pull_request`":{`"head`":{`"ref`":`"feat/test-none`"},`"labels`":[{`"name`":`"patch`"}]}}" Write-Host "Settings: ReleaseType=None, AutoPatching=false" @@ -525,7 +536,9 @@ jobs: @( [PSCustomObject]@{ Output = 'CreateRelease'; Expected = 'false'; Actual = $env:RESOLVE_CREATE_RELEASE; Passed = $env:RESOLVE_CREATE_RELEASE -eq 'false' } [PSCustomObject]@{ Output = 'ReleaseType'; Expected = 'None'; Actual = $env:RESOLVE_RELEASE_TYPE; Passed = $env:RESOLVE_RELEASE_TYPE -eq 'None' } - [PSCustomObject]@{ Output = 'Version'; Expected = '(empty)'; Actual = $env:RESOLVE_VERSION; Passed = [string]::IsNullOrEmpty($env:RESOLVE_VERSION) } + [PSCustomObject]@{ Output = 'Version'; Expected = $expectedVersion; Actual = $env:RESOLVE_VERSION; Passed = $env:RESOLVE_VERSION -eq $expectedVersion } + [PSCustomObject]@{ Output = 'Prerelease'; Expected = $expectedPrerelease; Actual = $env:RESOLVE_PRERELEASE; Passed = $env:RESOLVE_PRERELEASE -eq $expectedPrerelease } + [PSCustomObject]@{ Output = 'FullVersion'; Expected = $expectedFullVersion; Actual = $env:RESOLVE_FULL_VERSION; Passed = $env:RESOLVE_FULL_VERSION -eq $expectedFullVersion } ) | Format-Table -AutoSize | Out-String -Width 200 $failed = $false @@ -533,14 +546,22 @@ jobs: Write-Error "CreateRelease: expected 'false', got '$env:RESOLVE_CREATE_RELEASE'" $failed = $true } - if (-not [string]::IsNullOrEmpty($env:RESOLVE_VERSION)) { - Write-Error "Version: expected empty, got '$env:RESOLVE_VERSION'" - $failed = $true - } if ($env:RESOLVE_RELEASE_TYPE -ne 'None') { Write-Error "ReleaseType: expected 'None', got '$env:RESOLVE_RELEASE_TYPE'" $failed = $true } + if ($env:RESOLVE_VERSION -ne $expectedVersion) { + Write-Error "Version: expected '$expectedVersion', got '$env:RESOLVE_VERSION'" + $failed = $true + } + if ($env:RESOLVE_PRERELEASE -ne $expectedPrerelease) { + Write-Error "Prerelease: expected '$expectedPrerelease', got '$env:RESOLVE_PRERELEASE'" + $failed = $true + } + if ($env:RESOLVE_FULL_VERSION -ne $expectedFullVersion) { + Write-Error "FullVersion: expected '$expectedFullVersion', got '$env:RESOLVE_FULL_VERSION'" + $failed = $true + } if ($failed) { exit 1 } ActionTest-Prerelease: From c66bad1b4e6d6e2e1e41c68b5200456c2bb6162a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 21:11:43 +0200 Subject: [PATCH 09/19] fix: remove GH_TOKEN environment variable from Resolve-PSModuleVersion steps --- .github/workflows/Action-Test.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index 3085430..5dd4581 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -135,8 +135,6 @@ jobs: - name: Resolve-PSModuleVersion id: resolve uses: ./ - env: - GH_TOKEN: ${{ github.token }} with: Settings: | { @@ -229,8 +227,6 @@ jobs: - name: Resolve-PSModuleVersion id: resolve uses: ./ - env: - GH_TOKEN: ${{ github.token }} with: Settings: | { @@ -321,8 +317,6 @@ jobs: - name: Resolve-PSModuleVersion id: resolve uses: ./ - env: - GH_TOKEN: ${{ github.token }} with: Settings: | { @@ -416,8 +410,6 @@ jobs: - name: Resolve-PSModuleVersion id: resolve uses: ./ - env: - GH_TOKEN: ${{ github.token }} with: Settings: | { @@ -590,8 +582,6 @@ jobs: - name: Resolve-PSModuleVersion id: resolve uses: ./ - env: - GH_TOKEN: ${{ github.token }} with: Settings: | { From 8f88432929a9fb04b86afba3e41c4f0174e05aa3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 21:17:01 +0200 Subject: [PATCH 10/19] fix: always append incremental prerelease counter for non-publishable builds --- scripts/Helpers.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/Helpers.psm1 b/scripts/Helpers.psm1 index 5e97f90..6216af1 100644 --- a/scripts/Helpers.psm1 +++ b/scripts/Helpers.psm1 @@ -576,7 +576,7 @@ function Get-NextModuleVersion { $newVersion.Prerelease += "$(Get-Date -Format $Configuration.DatePrereleaseFormat)" } - if ($Configuration.IncrementalPrerelease) { + if ($Configuration.IncrementalPrerelease -or -not $Decision.ShouldPublish) { $baseVersionString = "$($newVersion.Major).$($newVersion.Minor).$($newVersion.Patch)" $params = @{ ModuleName = $ModuleName From 26a64662bfa1b93d8b62c14c68ba787d1f384433 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 21:24:42 +0200 Subject: [PATCH 11/19] refactor: replace inline workflow tests with data-driven Pester tests via PSModule/Invoke-Pester --- .github/workflows/Action-Test.yml | 649 +-------------------------- tests/Helpers.Tests.ps1 | 718 +++++++++++++++++++++++------- 2 files changed, 581 insertions(+), 786 deletions(-) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index 5dd4581..b774821 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -17,8 +17,8 @@ permissions: pull-requests: read jobs: - ActionTest-PatchBump: - name: Action-Test - [Patch bump] + Action-Test: + name: Action-Test runs-on: ubuntu-latest steps: - name: Checkout repo @@ -26,633 +26,28 @@ jobs: with: persist-credentials: false - - name: Create fake PR event - shell: pwsh - run: | - $event = @{ - pull_request = @{ - head = @{ ref = 'feat/test-patch' } - labels = @( - @{ name = 'patch' } - ) - } - } | ConvertTo-Json -Depth 5 - $event | Set-Content -Path "$env:RUNNER_TEMP/event.json" - "GITHUB_EVENT_PATH=$env:RUNNER_TEMP/event.json" | Out-File -FilePath $env:GITHUB_ENV -Append - - - name: Resolve-PSModuleVersion - id: resolve - uses: ./ - with: - Settings: | - { - "Publish": { - "Module": { - "ReleaseType": "Release", - "AutoPatching": false, - "VersionPrefix": "v", - "MajorLabels": "major", - "MinorLabels": "minor", - "PatchLabels": "patch", - "IgnoreLabels": "" - } - } - } - EventJson: '{"pull_request":{"head":{"ref":"feat/test-patch"},"labels":[{"name":"patch"}]}}' - - - name: Verify - Patch bump - shell: pwsh - env: - GH_TOKEN: ${{ github.token }} - RESOLVE_CREATE_RELEASE: ${{ steps.resolve.outputs.CreateRelease }} - RESOLVE_VERSION: ${{ steps.resolve.outputs.Version }} - RESOLVE_RELEASE_TYPE: ${{ steps.resolve.outputs.ReleaseType }} - RESOLVE_FULL_VERSION: ${{ steps.resolve.outputs.FullVersion }} - run: | - $PSStyle.OutputRendering = 'Ansi' - - $releases = (gh release list --json 'tagName,isLatest') | ConvertFrom-Json - $latestTag = ($releases | Where-Object { $_.isLatest }).tagName - if ([string]::IsNullOrEmpty($latestTag)) { $parts = @(0, 0, 0) } - else { $parts = ($latestTag -replace '^v', '').Split('.') | ForEach-Object { [int]$_ } } - $expectedVersion = "$($parts[0]).$($parts[1]).$($parts[2] + 1)" - $expectedFullVersion = "v$expectedVersion" - - Write-Host '--- Input ---' - Write-Host "EventJson: {`"pull_request`":{`"head`":{`"ref`":`"feat/test-patch`"},`"labels`":[{`"name`":`"patch`"}]}}" - Write-Host "Settings: ReleaseType=Release, AutoPatching=false, PatchLabels=patch" - Write-Host '' - - @( - [PSCustomObject]@{ Output = 'CreateRelease'; Expected = 'true'; Actual = $env:RESOLVE_CREATE_RELEASE; Passed = $env:RESOLVE_CREATE_RELEASE -eq 'true' } - [PSCustomObject]@{ Output = 'ReleaseType'; Expected = 'Release'; Actual = $env:RESOLVE_RELEASE_TYPE; Passed = $env:RESOLVE_RELEASE_TYPE -eq 'Release' } - [PSCustomObject]@{ Output = 'Version'; Expected = $expectedVersion; Actual = $env:RESOLVE_VERSION; Passed = $env:RESOLVE_VERSION -eq $expectedVersion } - [PSCustomObject]@{ Output = 'FullVersion'; Expected = $expectedFullVersion; Actual = $env:RESOLVE_FULL_VERSION; Passed = $env:RESOLVE_FULL_VERSION -eq $expectedFullVersion } - ) | Format-Table -AutoSize | Out-String -Width 200 - - $failed = $false - if ($env:RESOLVE_CREATE_RELEASE -ne 'true') { - Write-Error "CreateRelease: expected 'true', got '$env:RESOLVE_CREATE_RELEASE'" - $failed = $true - } - if ($env:RESOLVE_VERSION -ne $expectedVersion) { - Write-Error "Version: expected '$expectedVersion', got '$env:RESOLVE_VERSION'" - $failed = $true - } - if ($env:RESOLVE_RELEASE_TYPE -ne 'Release') { - Write-Error "ReleaseType: expected 'Release', got '$env:RESOLVE_RELEASE_TYPE'" - $failed = $true - } - if ($env:RESOLVE_FULL_VERSION -ne $expectedFullVersion) { - Write-Error "FullVersion: expected '$expectedFullVersion', got '$env:RESOLVE_FULL_VERSION'" - $failed = $true - } - if ($failed) { exit 1 } - - ActionTest-MinorBump: - name: Action-Test - [Minor bump] - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - - name: Create fake PR event - shell: pwsh - run: | - $event = @{ - pull_request = @{ - head = @{ ref = 'feat/test-minor' } - labels = @( - @{ name = 'minor' } - ) - } - } | ConvertTo-Json -Depth 5 - $event | Set-Content -Path "$env:RUNNER_TEMP/event.json" - "GITHUB_EVENT_PATH=$env:RUNNER_TEMP/event.json" | Out-File -FilePath $env:GITHUB_ENV -Append - - - name: Resolve-PSModuleVersion - id: resolve - uses: ./ - with: - Settings: | - { - "Publish": { - "Module": { - "ReleaseType": "Release", - "AutoPatching": false, - "VersionPrefix": "v", - "MajorLabels": "major", - "MinorLabels": "minor", - "PatchLabels": "patch", - "IgnoreLabels": "" - } - } - } - EventJson: '{"pull_request":{"head":{"ref":"feat/test-minor"},"labels":[{"name":"minor"}]}}' - - - name: Verify - Minor bump - shell: pwsh - env: - GH_TOKEN: ${{ github.token }} - RESOLVE_CREATE_RELEASE: ${{ steps.resolve.outputs.CreateRelease }} - RESOLVE_VERSION: ${{ steps.resolve.outputs.Version }} - RESOLVE_RELEASE_TYPE: ${{ steps.resolve.outputs.ReleaseType }} - RESOLVE_FULL_VERSION: ${{ steps.resolve.outputs.FullVersion }} - run: | - $PSStyle.OutputRendering = 'Ansi' - - $releases = (gh release list --json 'tagName,isLatest') | ConvertFrom-Json - $latestTag = ($releases | Where-Object { $_.isLatest }).tagName - if ([string]::IsNullOrEmpty($latestTag)) { $parts = @(0, 0, 0) } - else { $parts = ($latestTag -replace '^v', '').Split('.') | ForEach-Object { [int]$_ } } - $expectedVersion = "$($parts[0]).$($parts[1] + 1).0" - $expectedFullVersion = "v$expectedVersion" - - Write-Host '--- Input ---' - Write-Host "EventJson: {`"pull_request`":{`"head`":{`"ref`":`"feat/test-minor`"},`"labels`":[{`"name`":`"minor`"}]}}" - Write-Host "Settings: ReleaseType=Release, AutoPatching=false, MinorLabels=minor" - Write-Host '' - - @( - [PSCustomObject]@{ Output = 'CreateRelease'; Expected = 'true'; Actual = $env:RESOLVE_CREATE_RELEASE; Passed = $env:RESOLVE_CREATE_RELEASE -eq 'true' } - [PSCustomObject]@{ Output = 'ReleaseType'; Expected = 'Release'; Actual = $env:RESOLVE_RELEASE_TYPE; Passed = $env:RESOLVE_RELEASE_TYPE -eq 'Release' } - [PSCustomObject]@{ Output = 'Version'; Expected = $expectedVersion; Actual = $env:RESOLVE_VERSION; Passed = $env:RESOLVE_VERSION -eq $expectedVersion } - [PSCustomObject]@{ Output = 'FullVersion'; Expected = $expectedFullVersion; Actual = $env:RESOLVE_FULL_VERSION; Passed = $env:RESOLVE_FULL_VERSION -eq $expectedFullVersion } - ) | Format-Table -AutoSize | Out-String -Width 200 - - $failed = $false - if ($env:RESOLVE_CREATE_RELEASE -ne 'true') { - Write-Error "CreateRelease: expected 'true', got '$env:RESOLVE_CREATE_RELEASE'" - $failed = $true - } - if ($env:RESOLVE_VERSION -ne $expectedVersion) { - Write-Error "Version: expected '$expectedVersion', got '$env:RESOLVE_VERSION'" - $failed = $true - } - if ($env:RESOLVE_RELEASE_TYPE -ne 'Release') { - Write-Error "ReleaseType: expected 'Release', got '$env:RESOLVE_RELEASE_TYPE'" - $failed = $true - } - if ($env:RESOLVE_FULL_VERSION -ne $expectedFullVersion) { - Write-Error "FullVersion: expected '$expectedFullVersion', got '$env:RESOLVE_FULL_VERSION'" - $failed = $true - } - if ($failed) { exit 1 } - - ActionTest-MajorBump: - name: Action-Test - [Major bump] - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - - name: Create fake PR event - shell: pwsh - run: | - $event = @{ - pull_request = @{ - head = @{ ref = 'feat/test-major' } - labels = @( - @{ name = 'major' } - ) - } - } | ConvertTo-Json -Depth 5 - $event | Set-Content -Path "$env:RUNNER_TEMP/event.json" - "GITHUB_EVENT_PATH=$env:RUNNER_TEMP/event.json" | Out-File -FilePath $env:GITHUB_ENV -Append - - - name: Resolve-PSModuleVersion - id: resolve - uses: ./ - with: - Settings: | - { - "Publish": { - "Module": { - "ReleaseType": "Release", - "AutoPatching": false, - "VersionPrefix": "v", - "MajorLabels": "major", - "MinorLabels": "minor", - "PatchLabels": "patch", - "IgnoreLabels": "" - } - } - } - EventJson: '{"pull_request":{"head":{"ref":"feat/test-major"},"labels":[{"name":"major"}]}}' - - - name: Verify - Major bump - shell: pwsh - env: - GH_TOKEN: ${{ github.token }} - RESOLVE_CREATE_RELEASE: ${{ steps.resolve.outputs.CreateRelease }} - RESOLVE_VERSION: ${{ steps.resolve.outputs.Version }} - RESOLVE_RELEASE_TYPE: ${{ steps.resolve.outputs.ReleaseType }} - RESOLVE_FULL_VERSION: ${{ steps.resolve.outputs.FullVersion }} - run: | - $PSStyle.OutputRendering = 'Ansi' - - $releases = (gh release list --json 'tagName,isLatest') | ConvertFrom-Json - $latestTag = ($releases | Where-Object { $_.isLatest }).tagName - if ([string]::IsNullOrEmpty($latestTag)) { $parts = @(0, 0, 0) } - else { $parts = ($latestTag -replace '^v', '').Split('.') | ForEach-Object { [int]$_ } } - $expectedVersion = "$($parts[0] + 1).0.0" - $expectedFullVersion = "v$expectedVersion" - - Write-Host '--- Input ---' - Write-Host "EventJson: {`"pull_request`":{`"head`":{`"ref`":`"feat/test-major`"},`"labels`":[{`"name`":`"major`"}]}}" - Write-Host "Settings: ReleaseType=Release, AutoPatching=false, MajorLabels=major" - Write-Host '' - - @( - [PSCustomObject]@{ Output = 'CreateRelease'; Expected = 'true'; Actual = $env:RESOLVE_CREATE_RELEASE; Passed = $env:RESOLVE_CREATE_RELEASE -eq 'true' } - [PSCustomObject]@{ Output = 'ReleaseType'; Expected = 'Release'; Actual = $env:RESOLVE_RELEASE_TYPE; Passed = $env:RESOLVE_RELEASE_TYPE -eq 'Release' } - [PSCustomObject]@{ Output = 'Version'; Expected = $expectedVersion; Actual = $env:RESOLVE_VERSION; Passed = $env:RESOLVE_VERSION -eq $expectedVersion } - [PSCustomObject]@{ Output = 'FullVersion'; Expected = $expectedFullVersion; Actual = $env:RESOLVE_FULL_VERSION; Passed = $env:RESOLVE_FULL_VERSION -eq $expectedFullVersion } - ) | Format-Table -AutoSize | Out-String -Width 200 - - $failed = $false - if ($env:RESOLVE_CREATE_RELEASE -ne 'true') { - Write-Error "CreateRelease: expected 'true', got '$env:RESOLVE_CREATE_RELEASE'" - $failed = $true - } - if ($env:RESOLVE_VERSION -ne $expectedVersion) { - Write-Error "Version: expected '$expectedVersion', got '$env:RESOLVE_VERSION'" - $failed = $true - } - if ($env:RESOLVE_RELEASE_TYPE -ne 'Release') { - Write-Error "ReleaseType: expected 'Release', got '$env:RESOLVE_RELEASE_TYPE'" - $failed = $true - } - if ($env:RESOLVE_FULL_VERSION -ne $expectedFullVersion) { - Write-Error "FullVersion: expected '$expectedFullVersion', got '$env:RESOLVE_FULL_VERSION'" - $failed = $true - } - if ($failed) { exit 1 } - - ActionTest-AutoPatch: - name: Action-Test - [Auto-patch] - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - - name: Create fake PR event - shell: pwsh - run: | - $event = @{ - pull_request = @{ - head = @{ ref = 'feat/test-autopatch' } - labels = @() - } - } | ConvertTo-Json -Depth 5 - $event | Set-Content -Path "$env:RUNNER_TEMP/event.json" - "GITHUB_EVENT_PATH=$env:RUNNER_TEMP/event.json" | Out-File -FilePath $env:GITHUB_ENV -Append - - - name: Resolve-PSModuleVersion - id: resolve - uses: ./ - with: - Settings: | - { - "Publish": { - "Module": { - "ReleaseType": "Release", - "AutoPatching": true, - "VersionPrefix": "v", - "MajorLabels": "major", - "MinorLabels": "minor", - "PatchLabels": "patch", - "IgnoreLabels": "" - } - } - } - EventJson: '{"pull_request":{"head":{"ref":"feat/test-autopatch"},"labels":[]}}' - - - name: Verify - Auto-patch - shell: pwsh - env: - GH_TOKEN: ${{ github.token }} - RESOLVE_CREATE_RELEASE: ${{ steps.resolve.outputs.CreateRelease }} - RESOLVE_VERSION: ${{ steps.resolve.outputs.Version }} - RESOLVE_RELEASE_TYPE: ${{ steps.resolve.outputs.ReleaseType }} - RESOLVE_FULL_VERSION: ${{ steps.resolve.outputs.FullVersion }} - run: | - $PSStyle.OutputRendering = 'Ansi' - - $releases = (gh release list --json 'tagName,isLatest') | ConvertFrom-Json - $latestTag = ($releases | Where-Object { $_.isLatest }).tagName - if ([string]::IsNullOrEmpty($latestTag)) { $parts = @(0, 0, 0) } - else { $parts = ($latestTag -replace '^v', '').Split('.') | ForEach-Object { [int]$_ } } - $expectedVersion = "$($parts[0]).$($parts[1]).$($parts[2] + 1)" - $expectedFullVersion = "v$expectedVersion" - - Write-Host '--- Input ---' - Write-Host "EventJson: {`"pull_request`":{`"head`":{`"ref`":`"feat/test-autopatch`"},`"labels`":[]}}" - Write-Host "Settings: ReleaseType=Release, AutoPatching=true, PatchLabels=patch" - Write-Host '' - - @( - [PSCustomObject]@{ Output = 'CreateRelease'; Expected = 'true'; Actual = $env:RESOLVE_CREATE_RELEASE; Passed = $env:RESOLVE_CREATE_RELEASE -eq 'true' } - [PSCustomObject]@{ Output = 'ReleaseType'; Expected = 'Release'; Actual = $env:RESOLVE_RELEASE_TYPE; Passed = $env:RESOLVE_RELEASE_TYPE -eq 'Release' } - [PSCustomObject]@{ Output = 'Version'; Expected = $expectedVersion; Actual = $env:RESOLVE_VERSION; Passed = $env:RESOLVE_VERSION -eq $expectedVersion } - [PSCustomObject]@{ Output = 'FullVersion'; Expected = $expectedFullVersion; Actual = $env:RESOLVE_FULL_VERSION; Passed = $env:RESOLVE_FULL_VERSION -eq $expectedFullVersion } - ) | Format-Table -AutoSize | Out-String -Width 200 - - $failed = $false - if ($env:RESOLVE_CREATE_RELEASE -ne 'true') { - Write-Error "CreateRelease: expected 'true', got '$env:RESOLVE_CREATE_RELEASE'" - $failed = $true - } - if ($env:RESOLVE_VERSION -ne $expectedVersion) { - Write-Error "Version: expected '$expectedVersion', got '$env:RESOLVE_VERSION'" - $failed = $true - } - if ($env:RESOLVE_RELEASE_TYPE -ne 'Release') { - Write-Error "ReleaseType: expected 'Release', got '$env:RESOLVE_RELEASE_TYPE'" - $failed = $true - } - if ($env:RESOLVE_FULL_VERSION -ne $expectedFullVersion) { - Write-Error "FullVersion: expected '$expectedFullVersion', got '$env:RESOLVE_FULL_VERSION'" - $failed = $true - } - if ($failed) { exit 1 } - - ActionTest-IgnoreLabel: - name: Action-Test - [Ignore label] - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Run Pester tests + id: pester + uses: PSModule/Invoke-Pester@v4 with: - persist-credentials: false + Path: ./tests + Run_Path: ./scripts + TestResult_TestSuiteName: Resolve-PSModuleVersion - - name: Create fake PR event - shell: pwsh - run: | - $event = @{ - pull_request = @{ - head = @{ ref = 'feat/test-ignore' } - labels = @( - @{ name = 'patch' } - @{ name = 'skip-release' } - ) - } - } | ConvertTo-Json -Depth 5 - $event | Set-Content -Path "$env:RUNNER_TEMP/fake-event.json" - "GITHUB_EVENT_PATH=$env:RUNNER_TEMP/fake-event.json" | Out-File -FilePath $env:GITHUB_ENV -Append - - - name: Resolve-PSModuleVersion - id: resolve - uses: ./ - with: - Settings: | - { - "Publish": { - "Module": { - "ReleaseType": "Release", - "AutoPatching": false, - "VersionPrefix": "v", - "MajorLabels": "major", - "MinorLabels": "minor", - "PatchLabels": "patch", - "IgnoreLabels": "skip-release" - } - } - } - EventPath: ${{ runner.temp }}/fake-event.json - EventJson: '{"pull_request":{"head":{"ref":"feat/test-ignore"},"labels":[{"name":"patch"},{"name":"skip-release"}]}}' - - - name: Verify - Ignore label + - name: Check test outcome shell: pwsh + if: always() env: - RESOLVE_CREATE_RELEASE: ${{ steps.resolve.outputs.CreateRelease }} - RESOLVE_RELEASE_TYPE: ${{ steps.resolve.outputs.ReleaseType }} - run: | - $PSStyle.OutputRendering = 'Ansi' - - Write-Host '--- Input ---' - Write-Host "EventJson: {`"pull_request`":{`"head`":{`"ref`":`"feat/test-ignore`"},`"labels`":[{`"name`":`"patch`"},{`"name`":`"skip-release`"}]}}" - Write-Host "Settings: ReleaseType=Release, AutoPatching=false, IgnoreLabels=skip-release" - Write-Host '' - - @( - [PSCustomObject]@{ Output = 'CreateRelease'; Expected = 'false'; Actual = $env:RESOLVE_CREATE_RELEASE; Passed = $env:RESOLVE_CREATE_RELEASE -eq 'false' } - [PSCustomObject]@{ Output = 'ReleaseType'; Expected = 'None'; Actual = $env:RESOLVE_RELEASE_TYPE; Passed = $env:RESOLVE_RELEASE_TYPE -eq 'None' } - ) | Format-Table -AutoSize | Out-String -Width 200 - - $failed = $false - if ($env:RESOLVE_CREATE_RELEASE -ne 'false') { - Write-Error "CreateRelease: expected 'false', got '$env:RESOLVE_CREATE_RELEASE'" - $failed = $true - } - if ($env:RESOLVE_RELEASE_TYPE -ne 'None') { - Write-Error "ReleaseType: expected 'None', got '$env:RESOLVE_RELEASE_TYPE'" - $failed = $true - } - if ($failed) { exit 1 } - - ActionTest-None: - name: Action-Test - [None release type] - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - - name: Create fake PR event - shell: pwsh - run: | - $event = @{ - pull_request = @{ - head = @{ ref = 'feat/test-none' } - labels = @( - @{ name = 'patch' } - ) - } - } | ConvertTo-Json -Depth 5 - $event | Set-Content -Path "$env:RUNNER_TEMP/event.json" - "GITHUB_EVENT_PATH=$env:RUNNER_TEMP/event.json" | Out-File -FilePath $env:GITHUB_ENV -Append - - - name: Resolve-PSModuleVersion - id: resolve - uses: ./ - with: - Settings: | - { - "Publish": { - "Module": { - "ReleaseType": "None", - "AutoPatching": false, - "VersionPrefix": "v", - "MajorLabels": "major", - "MinorLabels": "minor", - "PatchLabels": "patch", - "IgnoreLabels": "" - } - } - } - EventJson: '{"pull_request":{"head":{"ref":"feat/test-none"},"labels":[{"name":"patch"}]}}' - - - name: Verify - None release type - shell: pwsh - env: - GH_TOKEN: ${{ github.token }} - RESOLVE_CREATE_RELEASE: ${{ steps.resolve.outputs.CreateRelease }} - RESOLVE_VERSION: ${{ steps.resolve.outputs.Version }} - RESOLVE_PRERELEASE: ${{ steps.resolve.outputs.Prerelease }} - RESOLVE_RELEASE_TYPE: ${{ steps.resolve.outputs.ReleaseType }} - RESOLVE_FULL_VERSION: ${{ steps.resolve.outputs.FullVersion }} - run: | - $PSStyle.OutputRendering = 'Ansi' - - $releases = (gh release list --json 'tagName,isLatest') | ConvertFrom-Json - $latestTag = ($releases | Where-Object { $_.isLatest }).tagName - if ([string]::IsNullOrEmpty($latestTag)) { $parts = @(0, 0, 0) } - else { $parts = ($latestTag -replace '^v', '').Split('.') | ForEach-Object { [int]$_ } } - $expectedVersion = "$($parts[0]).$($parts[1]).$($parts[2] + 1)" - $expectedPrerelease = 'feattestnone001' - $expectedFullVersion = "v$expectedVersion-$expectedPrerelease" - - Write-Host '--- Input ---' - Write-Host "EventJson: {`"pull_request`":{`"head`":{`"ref`":`"feat/test-none`"},`"labels`":[{`"name`":`"patch`"}]}}" - Write-Host "Settings: ReleaseType=None, AutoPatching=false" - Write-Host '' - - @( - [PSCustomObject]@{ Output = 'CreateRelease'; Expected = 'false'; Actual = $env:RESOLVE_CREATE_RELEASE; Passed = $env:RESOLVE_CREATE_RELEASE -eq 'false' } - [PSCustomObject]@{ Output = 'ReleaseType'; Expected = 'None'; Actual = $env:RESOLVE_RELEASE_TYPE; Passed = $env:RESOLVE_RELEASE_TYPE -eq 'None' } - [PSCustomObject]@{ Output = 'Version'; Expected = $expectedVersion; Actual = $env:RESOLVE_VERSION; Passed = $env:RESOLVE_VERSION -eq $expectedVersion } - [PSCustomObject]@{ Output = 'Prerelease'; Expected = $expectedPrerelease; Actual = $env:RESOLVE_PRERELEASE; Passed = $env:RESOLVE_PRERELEASE -eq $expectedPrerelease } - [PSCustomObject]@{ Output = 'FullVersion'; Expected = $expectedFullVersion; Actual = $env:RESOLVE_FULL_VERSION; Passed = $env:RESOLVE_FULL_VERSION -eq $expectedFullVersion } - ) | Format-Table -AutoSize | Out-String -Width 200 - - $failed = $false - if ($env:RESOLVE_CREATE_RELEASE -ne 'false') { - Write-Error "CreateRelease: expected 'false', got '$env:RESOLVE_CREATE_RELEASE'" - $failed = $true - } - if ($env:RESOLVE_RELEASE_TYPE -ne 'None') { - Write-Error "ReleaseType: expected 'None', got '$env:RESOLVE_RELEASE_TYPE'" - $failed = $true - } - if ($env:RESOLVE_VERSION -ne $expectedVersion) { - Write-Error "Version: expected '$expectedVersion', got '$env:RESOLVE_VERSION'" - $failed = $true - } - if ($env:RESOLVE_PRERELEASE -ne $expectedPrerelease) { - Write-Error "Prerelease: expected '$expectedPrerelease', got '$env:RESOLVE_PRERELEASE'" - $failed = $true - } - if ($env:RESOLVE_FULL_VERSION -ne $expectedFullVersion) { - Write-Error "FullVersion: expected '$expectedFullVersion', got '$env:RESOLVE_FULL_VERSION'" - $failed = $true - } - if ($failed) { exit 1 } - - ActionTest-Prerelease: - name: Action-Test - [Prerelease] - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - - name: Create fake PR event - shell: pwsh - run: | - $event = @{ - pull_request = @{ - head = @{ ref = 'feat/add-prerelease-support' } - labels = @( - @{ name = 'minor' } - ) - } - } | ConvertTo-Json -Depth 5 - $event | Set-Content -Path "$env:RUNNER_TEMP/event.json" - "GITHUB_EVENT_PATH=$env:RUNNER_TEMP/event.json" | Out-File -FilePath $env:GITHUB_ENV -Append - - - name: Resolve-PSModuleVersion - id: resolve - uses: ./ - with: - Settings: | - { - "Publish": { - "Module": { - "ReleaseType": "Prerelease", - "AutoPatching": false, - "IncrementalPrerelease": true, - "DatePrereleaseFormat": "", - "VersionPrefix": "v", - "MajorLabels": "major", - "MinorLabels": "minor", - "PatchLabels": "patch", - "IgnoreLabels": "" - } - } - } - EventJson: '{"pull_request":{"head":{"ref":"feat/add-prerelease-support"},"labels":[{"name":"minor"}]}}' - - - name: Verify - Prerelease - shell: pwsh - env: - GH_TOKEN: ${{ github.token }} - RESOLVE_CREATE_RELEASE: ${{ steps.resolve.outputs.CreateRelease }} - RESOLVE_VERSION: ${{ steps.resolve.outputs.Version }} - RESOLVE_PRERELEASE: ${{ steps.resolve.outputs.Prerelease }} - RESOLVE_RELEASE_TYPE: ${{ steps.resolve.outputs.ReleaseType }} - RESOLVE_FULL_VERSION: ${{ steps.resolve.outputs.FullVersion }} - run: | - $PSStyle.OutputRendering = 'Ansi' - - $releases = (gh release list --json 'tagName,isLatest') | ConvertFrom-Json - $latestTag = ($releases | Where-Object { $_.isLatest }).tagName - if ([string]::IsNullOrEmpty($latestTag)) { $parts = @(0, 0, 0) } - else { $parts = ($latestTag -replace '^v', '').Split('.') | ForEach-Object { [int]$_ } } - $expectedVersion = "$($parts[0]).$($parts[1] + 1).0" - $expectedPrerelease = 'feataddprereleasesupport001' - $expectedFullVersion = "v$expectedVersion-$expectedPrerelease" - - Write-Host '--- Input ---' - Write-Host "EventJson: {`"pull_request`":{`"head`":{`"ref`":`"feat/add-prerelease-support`"},`"labels`":[{`"name`":`"minor`"}]}}" - Write-Host "Settings: ReleaseType=Prerelease, AutoPatching=false, IncrementalPrerelease=true, MinorLabels=minor" - Write-Host '' - - @( - [PSCustomObject]@{ Output = 'CreateRelease'; Expected = 'true'; Actual = $env:RESOLVE_CREATE_RELEASE; Passed = $env:RESOLVE_CREATE_RELEASE -eq 'true' } - [PSCustomObject]@{ Output = 'ReleaseType'; Expected = 'Prerelease'; Actual = $env:RESOLVE_RELEASE_TYPE; Passed = $env:RESOLVE_RELEASE_TYPE -eq 'Prerelease' } - [PSCustomObject]@{ Output = 'Version'; Expected = $expectedVersion; Actual = $env:RESOLVE_VERSION; Passed = $env:RESOLVE_VERSION -eq $expectedVersion } - [PSCustomObject]@{ Output = 'Prerelease'; Expected = $expectedPrerelease; Actual = $env:RESOLVE_PRERELEASE; Passed = $env:RESOLVE_PRERELEASE -eq $expectedPrerelease } - [PSCustomObject]@{ Output = 'FullVersion'; Expected = $expectedFullVersion; Actual = $env:RESOLVE_FULL_VERSION; Passed = $env:RESOLVE_FULL_VERSION -eq $expectedFullVersion } - ) | Format-Table -AutoSize | Out-String -Width 200 - - $failed = $false - if ($env:RESOLVE_CREATE_RELEASE -ne 'true') { - Write-Error "CreateRelease: expected 'true', got '$env:RESOLVE_CREATE_RELEASE'" - $failed = $true - } - if ($env:RESOLVE_RELEASE_TYPE -ne 'Prerelease') { - Write-Error "ReleaseType: expected 'Prerelease', got '$env:RESOLVE_RELEASE_TYPE'" - $failed = $true - } - if ($env:RESOLVE_VERSION -ne $expectedVersion) { - Write-Error "Version: expected '$expectedVersion', got '$env:RESOLVE_VERSION'" - $failed = $true - } - if ($env:RESOLVE_PRERELEASE -ne $expectedPrerelease) { - Write-Error "Prerelease: expected '$expectedPrerelease', got '$env:RESOLVE_PRERELEASE'" - $failed = $true - } - if ($env:RESOLVE_FULL_VERSION -ne $expectedFullVersion) { - Write-Error "FullVersion: expected '$expectedFullVersion', got '$env:RESOLVE_FULL_VERSION'" - $failed = $true + OUTCOME: ${{ steps.pester.outcome }} + PASSED: ${{ steps.pester.outputs.PassedCount }} + FAILED: ${{ steps.pester.outputs.FailedCount }} + TOTAL: ${{ steps.pester.outputs.TotalCount }} + run: | + Write-Host "Outcome: [$env:OUTCOME]" + Write-Host "Passed: [$env:PASSED]" + Write-Host "Failed: [$env:FAILED]" + Write-Host "Total: [$env:TOTAL]" + if ($env:OUTCOME -ne 'success') { + Write-Error 'Pester tests did not pass.' + exit 1 } - if ($failed) { exit 1 } diff --git a/tests/Helpers.Tests.ps1 b/tests/Helpers.Tests.ps1 index 6023f71..21ac9b0 100644 --- a/tests/Helpers.Tests.ps1 +++ b/tests/Helpers.Tests.ps1 @@ -17,200 +17,600 @@ BeforeAll { Import-Module -Name "$PSScriptRoot/../scripts/Helpers.psm1" -Force } -Describe 'Non-publishable builds emit a prerelease version via Get-NextModuleVersion' { +Describe 'Resolve-ReleaseDecision' { BeforeAll { $baseConfig = [PSCustomObject]@{ AutoPatching = $false IncrementalPrerelease = $false DatePrereleaseFormat = '' VersionPrefix = 'v' - ReleaseType = 'None' - IgnoreLabels = @() - MajorLabels = @('Major') - MinorLabels = @('Minor') - PatchLabels = @('Patch') + ReleaseType = 'Release' + IgnoreLabels = @('skip-release') + MajorLabels = @('major') + MinorLabels = @('minor') + PatchLabels = @('patch') } - # Use a placeholder release so the mandatory [array] parameter binds - $emptyReleases = @([PSCustomObject]@{ tagName = 'v0.0.0'; isLatest = $false; isPrerelease = $false }) - } - - It 'Emits a version when ReleaseType is None (synthesized prerelease decision)' { - $decision = [PSCustomObject]@{ - ShouldPublish = $true - CreateRelease = $false - CreatePrerelease = $true - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = 'featurebranch' - } - $latestVersion = New-PSSemVer -Version '1.2.3' - - $result = Get-NextModuleVersion -LatestVersion $latestVersion -Decision $decision ` - -Configuration $baseConfig -ModuleName 'TestModule' -Releases $emptyReleases - - $result | Should -Not -BeNullOrEmpty - "$($result.Major).$($result.Minor).$($result.Patch)" | Should -Be '1.2.4' - $result.Prerelease | Should -Be 'featurebranch' } - It 'Emits a version when ignore label is present (synthesized prerelease decision)' { - $decision = [PSCustomObject]@{ - ShouldPublish = $true - CreateRelease = $false - CreatePrerelease = $true - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = 'mybranch' - } - $latestVersion = New-PSSemVer -Version '2.0.0' - - $result = Get-NextModuleVersion -LatestVersion $latestVersion -Decision $decision ` - -Configuration $baseConfig -ModuleName 'TestModule' -Releases $emptyReleases + Context '' -ForEach @( + @{ + Name = 'Patch label with Release type' + ReleaseType = 'Release' + AutoPatching = $false + HeadRef = 'feat/test-patch' + Labels = @('patch') + Expected = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'feattestpatch' + } + } + @{ + Name = 'Minor label with Release type' + ReleaseType = 'Release' + AutoPatching = $false + HeadRef = 'feat/test-minor' + Labels = @('minor') + Expected = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $true + PatchRelease = $false + HasVersionBump = $true + PrereleaseName = 'feattestminor' + } + } + @{ + Name = 'Major label with Release type' + ReleaseType = 'Release' + AutoPatching = $false + HeadRef = 'feat/test-major' + Labels = @('major') + Expected = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $true + MinorRelease = $false + PatchRelease = $false + HasVersionBump = $true + PrereleaseName = 'feattestmajor' + } + } + @{ + Name = 'AutoPatching with no label' + ReleaseType = 'Release' + AutoPatching = $true + HeadRef = 'feat/test-autopatch' + Labels = @() + Expected = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'feattestautopatch' + } + } + @{ + Name = 'Ignore label suppresses release' + ReleaseType = 'Release' + AutoPatching = $false + HeadRef = 'feat/test-ignore' + Labels = @('patch', 'skip-release') + Expected = @{ + ShouldPublish = $false + CreateRelease = $true + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'feattestignore' + } + } + @{ + Name = 'ReleaseType None produces prerelease' + ReleaseType = 'None' + AutoPatching = $false + HeadRef = 'feat/test-none' + Labels = @('patch') + Expected = @{ + ShouldPublish = $false + CreateRelease = $false + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'feattestnone' + } + } + @{ + Name = 'ReleaseType Prerelease with minor label' + ReleaseType = 'Prerelease' + AutoPatching = $false + HeadRef = 'feat/add-prerelease-support' + Labels = @('minor') + Expected = @{ + ShouldPublish = $true + CreateRelease = $false + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $true + PatchRelease = $false + HasVersionBump = $true + PrereleaseName = 'feataddprereleasesupport' + } + } + @{ + Name = 'No bump label and no AutoPatching falls back to prerelease' + ReleaseType = 'Release' + AutoPatching = $false + HeadRef = 'feat/no-label' + Labels = @() + Expected = @{ + ShouldPublish = $false + CreateRelease = $true + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'featnolabel' + } + } + ) { + BeforeAll { + $config = [PSCustomObject]@{ + AutoPatching = $AutoPatching + IncrementalPrerelease = $baseConfig.IncrementalPrerelease + DatePrereleaseFormat = $baseConfig.DatePrereleaseFormat + VersionPrefix = $baseConfig.VersionPrefix + ReleaseType = $ReleaseType + IgnoreLabels = $baseConfig.IgnoreLabels + MajorLabels = $baseConfig.MajorLabels + MinorLabels = $baseConfig.MinorLabels + PatchLabels = $baseConfig.PatchLabels + } + $pullRequest = [PSCustomObject]@{ + HeadRef = $HeadRef + Labels = $Labels + } + $result = Resolve-ReleaseDecision -Configuration $config -PullRequest $pullRequest + } - $result | Should -Not -BeNullOrEmpty - "$($result.Major).$($result.Minor).$($result.Patch)" | Should -Be '2.0.1' - $result.Prerelease | Should -Be 'mybranch' + It 'ShouldPublish is ' { + $result.ShouldPublish | Should -Be $Expected.ShouldPublish + } + It 'CreateRelease is ' { + $result.CreateRelease | Should -Be $Expected.CreateRelease + } + It 'CreatePrerelease is ' { + $result.CreatePrerelease | Should -Be $Expected.CreatePrerelease + } + It 'MajorRelease is ' { + $result.MajorRelease | Should -Be $Expected.MajorRelease + } + It 'MinorRelease is ' { + $result.MinorRelease | Should -Be $Expected.MinorRelease + } + It 'PatchRelease is ' { + $result.PatchRelease | Should -Be $Expected.PatchRelease + } + It 'HasVersionBump is ' { + $result.HasVersionBump | Should -Be $Expected.HasVersionBump + } + It 'PrereleaseName is ' { + $result.PrereleaseName | Should -Be $Expected.PrereleaseName + } } +} - It 'Emits a version when no version bump label and AutoPatching is false (synthesized prerelease decision)' { - $decision = [PSCustomObject]@{ - ShouldPublish = $true - CreateRelease = $false - CreatePrerelease = $true - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = 'fixsomething' - } - $latestVersion = New-PSSemVer -Version '0.0.0' - - $result = Get-NextModuleVersion -LatestVersion $latestVersion -Decision $decision ` - -Configuration $baseConfig -ModuleName 'TestModule' -Releases $emptyReleases - - $result | Should -Not -BeNullOrEmpty - "$($result.Major).$($result.Minor).$($result.Patch)" | Should -Be '0.0.1' - $result.Prerelease | Should -Be 'fixsomething' +Describe 'Get-NextModuleVersion' { + BeforeAll { + $emptyReleases = @([PSCustomObject]@{ tagName = 'v0.0.0'; isLatest = $false; isPrerelease = $false }) } - It 'Applies version prefix from configuration' { - $decision = [PSCustomObject]@{ - ShouldPublish = $true - CreateRelease = $false - CreatePrerelease = $true - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = 'dev' - } - $latestVersion = New-PSSemVer -Version '1.0.0' - - $result = Get-NextModuleVersion -LatestVersion $latestVersion -Decision $decision ` - -Configuration $baseConfig -ModuleName 'TestModule' -Releases $emptyReleases + Context '' -ForEach @( + @{ + Name = 'Patch bump - Release' + LatestVersion = '1.0.1' + VersionPrefix = 'v' + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'feattestpatch' + } + ExpectedVersion = '1.0.2' + ExpectedPrerelease = '' + ExpectedPrefix = 'v' + } + @{ + Name = 'Minor bump - Release' + LatestVersion = '1.0.1' + VersionPrefix = 'v' + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $true + PatchRelease = $false + HasVersionBump = $true + PrereleaseName = 'feattestminor' + } + ExpectedVersion = '1.1.0' + ExpectedPrerelease = '' + ExpectedPrefix = 'v' + } + @{ + Name = 'Major bump - Release' + LatestVersion = '1.2.3' + VersionPrefix = 'v' + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $true + MinorRelease = $false + PatchRelease = $false + HasVersionBump = $true + PrereleaseName = 'feattestmajor' + } + ExpectedVersion = '2.0.0' + ExpectedPrerelease = '' + ExpectedPrefix = 'v' + } + @{ + Name = 'ReleaseType None - prerelease with incremental counter' + LatestVersion = '1.0.1' + VersionPrefix = 'v' + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $false + CreateRelease = $false + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'feattestnone' + } + ExpectedVersion = '1.0.2' + ExpectedPrerelease = 'feattestnone001' + ExpectedPrefix = 'v' + } + @{ + Name = 'Prerelease type with IncrementalPrerelease' + LatestVersion = '1.0.1' + VersionPrefix = 'v' + IncrementalPrerelease = $true + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $true + CreateRelease = $false + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $true + PatchRelease = $false + HasVersionBump = $true + PrereleaseName = 'feataddprereleasesupport' + } + ExpectedVersion = '1.1.0' + ExpectedPrerelease = 'feataddprereleasesupport001' + ExpectedPrefix = 'v' + } + @{ + Name = 'Ignore label falls back to prerelease with counter' + LatestVersion = '1.0.1' + VersionPrefix = 'v' + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $false + CreateRelease = $true + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'feattestignore' + } + ExpectedVersion = '1.0.2' + ExpectedPrerelease = 'feattestignore001' + ExpectedPrefix = 'v' + } + @{ + Name = 'No version prefix' + LatestVersion = '2.0.0' + VersionPrefix = '' + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'main' + } + ExpectedVersion = '2.0.1' + ExpectedPrerelease = '' + ExpectedPrefix = '' + } + @{ + Name = 'AutoPatch - Release with no label' + LatestVersion = '1.0.1' + VersionPrefix = 'v' + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'feattestautopatch' + } + ExpectedVersion = '1.0.2' + ExpectedPrerelease = '' + ExpectedPrefix = 'v' + } + @{ + Name = 'Prerelease without IncrementalPrerelease but ShouldPublish true' + LatestVersion = '1.0.0' + VersionPrefix = 'v' + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $true + CreateRelease = $false + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'dev' + } + ExpectedVersion = '1.0.1' + ExpectedPrerelease = 'dev' + ExpectedPrefix = 'v' + } + ) { + BeforeAll { + $config = [PSCustomObject]@{ + AutoPatching = $false + IncrementalPrerelease = $IncrementalPrerelease + DatePrereleaseFormat = $DatePrereleaseFormat + VersionPrefix = $VersionPrefix + ReleaseType = 'Release' + IgnoreLabels = @() + MajorLabels = @('major') + MinorLabels = @('minor') + PatchLabels = @('patch') + } + $decisionObj = [PSCustomObject]$Decision + $latestVer = New-PSSemVer -Version $LatestVersion + $result = Get-NextModuleVersion -LatestVersion $latestVer -Decision $decisionObj ` + -Configuration $config -ModuleName 'TestModule' -Releases $emptyReleases + } - $result.Prefix | Should -Be 'v' - $result.ToString() | Should -BeLike 'v1.0.1-dev*' + It 'Version is ' { + "$($result.Major).$($result.Minor).$($result.Patch)" | Should -Be $ExpectedVersion + } + It 'Prerelease is ' { + if ([string]::IsNullOrEmpty($ExpectedPrerelease)) { + $result.Prerelease | Should -BeNullOrEmpty + } else { + $result.Prerelease | Should -Be $ExpectedPrerelease + } + } + It 'Prefix is ' { + $result.Prefix | Should -Be $ExpectedPrefix + } } } -Describe 'Get-NextModuleVersion - existing behavior unchanged' { +Describe 'End-to-end: Resolve-ReleaseDecision + Get-NextModuleVersion' { BeforeAll { $emptyReleases = @([PSCustomObject]@{ tagName = 'v0.0.0'; isLatest = $false; isPrerelease = $false }) } - It 'Correctly bumps major version' { - $decision = [PSCustomObject]@{ - ShouldPublish = $true - CreateRelease = $true - CreatePrerelease = $false - MajorRelease = $true - MinorRelease = $false - PatchRelease = $false - HasVersionBump = $true - PrereleaseName = 'main' - } - $config = [PSCustomObject]@{ + Context '' -ForEach @( + @{ + Name = 'Patch bump produces release version' + LatestVersion = '1.0.1' + ReleaseType = 'Release' AutoPatching = $false IncrementalPrerelease = $false - DatePrereleaseFormat = '' - VersionPrefix = '' + VersionPrefix = 'v' + HeadRef = 'feat/test-patch' + Labels = @('patch') + ExpectedCreateRelease = $true + ExpectedReleaseType = 'Release' + ExpectedVersion = '1.0.2' + ExpectedPrerelease = '' + ExpectedFullVersion = 'v1.0.2' + } + @{ + Name = 'Minor bump produces release version' + LatestVersion = '1.0.1' ReleaseType = 'Release' - IgnoreLabels = @() - MajorLabels = @('Major') - MinorLabels = @('Minor') - PatchLabels = @('Patch') + AutoPatching = $false + IncrementalPrerelease = $false + VersionPrefix = 'v' + HeadRef = 'feat/test-minor' + Labels = @('minor') + ExpectedCreateRelease = $true + ExpectedReleaseType = 'Release' + ExpectedVersion = '1.1.0' + ExpectedPrerelease = '' + ExpectedFullVersion = 'v1.1.0' } - $latestVersion = New-PSSemVer -Version '1.2.3' - - $result = Get-NextModuleVersion -LatestVersion $latestVersion -Decision $decision ` - -Configuration $config -ModuleName 'TestModule' -Releases $emptyReleases - - "$($result.Major).$($result.Minor).$($result.Patch)" | Should -Be '2.0.0' - $result.Prerelease | Should -BeNullOrEmpty - } - - It 'Correctly bumps minor version' { - $decision = [PSCustomObject]@{ - ShouldPublish = $true - CreateRelease = $true - CreatePrerelease = $false - MajorRelease = $false - MinorRelease = $true - PatchRelease = $false - HasVersionBump = $true - PrereleaseName = 'main' - } - $config = [PSCustomObject]@{ + @{ + Name = 'Major bump produces release version' + LatestVersion = '1.0.1' + ReleaseType = 'Release' AutoPatching = $false IncrementalPrerelease = $false - DatePrereleaseFormat = '' - VersionPrefix = '' + VersionPrefix = 'v' + HeadRef = 'feat/test-major' + Labels = @('major') + ExpectedCreateRelease = $true + ExpectedReleaseType = 'Release' + ExpectedVersion = '2.0.0' + ExpectedPrerelease = '' + ExpectedFullVersion = 'v2.0.0' + } + @{ + Name = 'Auto-patch with no label produces release version' + LatestVersion = '1.0.1' ReleaseType = 'Release' - IgnoreLabels = @() - MajorLabels = @('Major') - MinorLabels = @('Minor') - PatchLabels = @('Patch') + AutoPatching = $true + IncrementalPrerelease = $false + VersionPrefix = 'v' + HeadRef = 'feat/test-autopatch' + Labels = @() + ExpectedCreateRelease = $true + ExpectedReleaseType = 'Release' + ExpectedVersion = '1.0.2' + ExpectedPrerelease = '' + ExpectedFullVersion = 'v1.0.2' } - $latestVersion = New-PSSemVer -Version '1.2.3' - - $result = Get-NextModuleVersion -LatestVersion $latestVersion -Decision $decision ` - -Configuration $config -ModuleName 'TestModule' -Releases $emptyReleases - - "$($result.Major).$($result.Minor).$($result.Patch)" | Should -Be '1.3.0' - } - - It 'Correctly bumps patch version' { - $decision = [PSCustomObject]@{ - ShouldPublish = $true - CreateRelease = $true - CreatePrerelease = $false - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = 'main' - } - $config = [PSCustomObject]@{ + @{ + Name = 'Ignore label suppresses release, produces prerelease' + LatestVersion = '1.0.1' + ReleaseType = 'Release' AutoPatching = $false IncrementalPrerelease = $false - DatePrereleaseFormat = '' - VersionPrefix = '' + VersionPrefix = 'v' + HeadRef = 'feat/test-ignore' + Labels = @('patch', 'skip-release') + ExpectedCreateRelease = $false + ExpectedReleaseType = 'None' + ExpectedVersion = '1.0.2' + ExpectedPrerelease = 'feattestignore001' + ExpectedFullVersion = 'v1.0.2-feattestignore001' + } + @{ + Name = 'ReleaseType None produces prerelease with counter' + LatestVersion = '1.0.1' + ReleaseType = 'None' + AutoPatching = $false + IncrementalPrerelease = $false + VersionPrefix = 'v' + HeadRef = 'feat/test-none' + Labels = @('patch') + ExpectedCreateRelease = $false + ExpectedReleaseType = 'None' + ExpectedVersion = '1.0.2' + ExpectedPrerelease = 'feattestnone001' + ExpectedFullVersion = 'v1.0.2-feattestnone001' + } + @{ + Name = 'Prerelease type with incremental counter' + LatestVersion = '1.0.1' + ReleaseType = 'Prerelease' + AutoPatching = $false + IncrementalPrerelease = $true + VersionPrefix = 'v' + HeadRef = 'feat/add-prerelease-support' + Labels = @('minor') + ExpectedCreateRelease = $true + ExpectedReleaseType = 'Prerelease' + ExpectedVersion = '1.1.0' + ExpectedPrerelease = 'feataddprereleasesupport001' + ExpectedFullVersion = 'v1.1.0-feataddprereleasesupport001' + } + @{ + Name = 'No label and no AutoPatching falls back to prerelease' + LatestVersion = '1.0.1' ReleaseType = 'Release' - IgnoreLabels = @() - MajorLabels = @('Major') - MinorLabels = @('Minor') - PatchLabels = @('Patch') + AutoPatching = $false + IncrementalPrerelease = $false + VersionPrefix = 'v' + HeadRef = 'feat/no-label' + Labels = @() + ExpectedCreateRelease = $false + ExpectedReleaseType = 'None' + ExpectedVersion = '1.0.2' + ExpectedPrerelease = 'featnolabel001' + ExpectedFullVersion = 'v1.0.2-featnolabel001' } - $latestVersion = New-PSSemVer -Version '1.2.3' + ) { + BeforeAll { + $config = [PSCustomObject]@{ + AutoPatching = $AutoPatching + IncrementalPrerelease = $IncrementalPrerelease + DatePrereleaseFormat = '' + VersionPrefix = $VersionPrefix + ReleaseType = $ReleaseType + IgnoreLabels = @('skip-release') + MajorLabels = @('major') + MinorLabels = @('minor') + PatchLabels = @('patch') + } + $pullRequest = [PSCustomObject]@{ + HeadRef = $HeadRef + Labels = $Labels + } + $decision = Resolve-ReleaseDecision -Configuration $config -PullRequest $pullRequest + $latestVer = New-PSSemVer -Version $LatestVersion + $newVersion = Get-NextModuleVersion -LatestVersion $latestVer -Decision $decision ` + -Configuration $config -ModuleName 'TestModule' -Releases $emptyReleases - $result = Get-NextModuleVersion -LatestVersion $latestVersion -Decision $decision ` - -Configuration $config -ModuleName 'TestModule' -Releases $emptyReleases + # Derive resolved release type the same way Write-ActionOutput does + $resolvedReleaseType = if ($decision.ShouldPublish) { + if ($decision.CreateRelease) { 'Release' } else { 'Prerelease' } + } else { + 'None' + } + } - "$($result.Major).$($result.Minor).$($result.Patch)" | Should -Be '1.2.4' + It 'CreateRelease is ' { + $decision.ShouldPublish | Should -Be $ExpectedCreateRelease + } + It 'ReleaseType is ' { + $resolvedReleaseType | Should -Be $ExpectedReleaseType + } + It 'Version is ' { + "$($newVersion.Major).$($newVersion.Minor).$($newVersion.Patch)" | Should -Be $ExpectedVersion + } + It 'Prerelease is ' { + if ([string]::IsNullOrEmpty($ExpectedPrerelease)) { + $newVersion.Prerelease | Should -BeNullOrEmpty + } else { + $newVersion.Prerelease | Should -Be $ExpectedPrerelease + } + } + It 'FullVersion is ' { + $newVersion.ToString() | Should -Be $ExpectedFullVersion + } } } From fa528c1438a069b919d1a26c99763bc055457f1c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 21:28:59 +0200 Subject: [PATCH 12/19] refactor: extract test data into separate Helpers.Tests.Data.psd1 file --- tests/Helpers.Tests.Data.psd1 | 446 +++++++++++++++++++++++++++++++++ tests/Helpers.Tests.ps1 | 448 +--------------------------------- 2 files changed, 452 insertions(+), 442 deletions(-) create mode 100644 tests/Helpers.Tests.Data.psd1 diff --git a/tests/Helpers.Tests.Data.psd1 b/tests/Helpers.Tests.Data.psd1 new file mode 100644 index 0000000..ad7aca2 --- /dev/null +++ b/tests/Helpers.Tests.Data.psd1 @@ -0,0 +1,446 @@ +@{ + ReleaseDecision = @( + @{ + Name = 'Patch label with Release type' + ReleaseType = 'Release' + AutoPatching = $false + HeadRef = 'feat/test-patch' + Labels = @('patch') + Expected = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'feattestpatch' + } + } + @{ + Name = 'Minor label with Release type' + ReleaseType = 'Release' + AutoPatching = $false + HeadRef = 'feat/test-minor' + Labels = @('minor') + Expected = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $true + PatchRelease = $false + HasVersionBump = $true + PrereleaseName = 'feattestminor' + } + } + @{ + Name = 'Major label with Release type' + ReleaseType = 'Release' + AutoPatching = $false + HeadRef = 'feat/test-major' + Labels = @('major') + Expected = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $true + MinorRelease = $false + PatchRelease = $false + HasVersionBump = $true + PrereleaseName = 'feattestmajor' + } + } + @{ + Name = 'AutoPatching with no label' + ReleaseType = 'Release' + AutoPatching = $true + HeadRef = 'feat/test-autopatch' + Labels = @() + Expected = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'feattestautopatch' + } + } + @{ + Name = 'Ignore label suppresses release' + ReleaseType = 'Release' + AutoPatching = $false + HeadRef = 'feat/test-ignore' + Labels = @('patch', 'skip-release') + Expected = @{ + ShouldPublish = $false + CreateRelease = $true + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'feattestignore' + } + } + @{ + Name = 'ReleaseType None produces prerelease' + ReleaseType = 'None' + AutoPatching = $false + HeadRef = 'feat/test-none' + Labels = @('patch') + Expected = @{ + ShouldPublish = $false + CreateRelease = $false + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'feattestnone' + } + } + @{ + Name = 'ReleaseType Prerelease with minor label' + ReleaseType = 'Prerelease' + AutoPatching = $false + HeadRef = 'feat/add-prerelease-support' + Labels = @('minor') + Expected = @{ + ShouldPublish = $true + CreateRelease = $false + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $true + PatchRelease = $false + HasVersionBump = $true + PrereleaseName = 'feataddprereleasesupport' + } + } + @{ + Name = 'No bump label and no AutoPatching falls back to prerelease' + ReleaseType = 'Release' + AutoPatching = $false + HeadRef = 'feat/no-label' + Labels = @() + Expected = @{ + ShouldPublish = $false + CreateRelease = $true + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'featnolabel' + } + } + ) + + NextModuleVersion = @( + @{ + Name = 'Patch bump - Release' + LatestVersion = '1.0.1' + VersionPrefix = 'v' + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'feattestpatch' + } + ExpectedVersion = '1.0.2' + ExpectedPrerelease = '' + ExpectedPrefix = 'v' + } + @{ + Name = 'Minor bump - Release' + LatestVersion = '1.0.1' + VersionPrefix = 'v' + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $true + PatchRelease = $false + HasVersionBump = $true + PrereleaseName = 'feattestminor' + } + ExpectedVersion = '1.1.0' + ExpectedPrerelease = '' + ExpectedPrefix = 'v' + } + @{ + Name = 'Major bump - Release' + LatestVersion = '1.2.3' + VersionPrefix = 'v' + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $true + MinorRelease = $false + PatchRelease = $false + HasVersionBump = $true + PrereleaseName = 'feattestmajor' + } + ExpectedVersion = '2.0.0' + ExpectedPrerelease = '' + ExpectedPrefix = 'v' + } + @{ + Name = 'ReleaseType None - prerelease with incremental counter' + LatestVersion = '1.0.1' + VersionPrefix = 'v' + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $false + CreateRelease = $false + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'feattestnone' + } + ExpectedVersion = '1.0.2' + ExpectedPrerelease = 'feattestnone001' + ExpectedPrefix = 'v' + } + @{ + Name = 'Prerelease type with IncrementalPrerelease' + LatestVersion = '1.0.1' + VersionPrefix = 'v' + IncrementalPrerelease = $true + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $true + CreateRelease = $false + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $true + PatchRelease = $false + HasVersionBump = $true + PrereleaseName = 'feataddprereleasesupport' + } + ExpectedVersion = '1.1.0' + ExpectedPrerelease = 'feataddprereleasesupport001' + ExpectedPrefix = 'v' + } + @{ + Name = 'Ignore label falls back to prerelease with counter' + LatestVersion = '1.0.1' + VersionPrefix = 'v' + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $false + CreateRelease = $true + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'feattestignore' + } + ExpectedVersion = '1.0.2' + ExpectedPrerelease = 'feattestignore001' + ExpectedPrefix = 'v' + } + @{ + Name = 'No version prefix' + LatestVersion = '2.0.0' + VersionPrefix = '' + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'main' + } + ExpectedVersion = '2.0.1' + ExpectedPrerelease = '' + ExpectedPrefix = '' + } + @{ + Name = 'AutoPatch - Release with no label' + LatestVersion = '1.0.1' + VersionPrefix = 'v' + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $true + CreateRelease = $true + CreatePrerelease = $false + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'feattestautopatch' + } + ExpectedVersion = '1.0.2' + ExpectedPrerelease = '' + ExpectedPrefix = 'v' + } + @{ + Name = 'Prerelease without IncrementalPrerelease but ShouldPublish true' + LatestVersion = '1.0.0' + VersionPrefix = 'v' + IncrementalPrerelease = $false + DatePrereleaseFormat = '' + Decision = @{ + ShouldPublish = $true + CreateRelease = $false + CreatePrerelease = $true + MajorRelease = $false + MinorRelease = $false + PatchRelease = $true + HasVersionBump = $true + PrereleaseName = 'dev' + } + ExpectedVersion = '1.0.1' + ExpectedPrerelease = 'dev' + ExpectedPrefix = 'v' + } + ) + + EndToEnd = @( + @{ + Name = 'Patch bump produces release version' + LatestVersion = '1.0.1' + ReleaseType = 'Release' + AutoPatching = $false + IncrementalPrerelease = $false + VersionPrefix = 'v' + HeadRef = 'feat/test-patch' + Labels = @('patch') + ExpectedCreateRelease = $true + ExpectedReleaseType = 'Release' + ExpectedVersion = '1.0.2' + ExpectedPrerelease = '' + ExpectedFullVersion = 'v1.0.2' + } + @{ + Name = 'Minor bump produces release version' + LatestVersion = '1.0.1' + ReleaseType = 'Release' + AutoPatching = $false + IncrementalPrerelease = $false + VersionPrefix = 'v' + HeadRef = 'feat/test-minor' + Labels = @('minor') + ExpectedCreateRelease = $true + ExpectedReleaseType = 'Release' + ExpectedVersion = '1.1.0' + ExpectedPrerelease = '' + ExpectedFullVersion = 'v1.1.0' + } + @{ + Name = 'Major bump produces release version' + LatestVersion = '1.0.1' + ReleaseType = 'Release' + AutoPatching = $false + IncrementalPrerelease = $false + VersionPrefix = 'v' + HeadRef = 'feat/test-major' + Labels = @('major') + ExpectedCreateRelease = $true + ExpectedReleaseType = 'Release' + ExpectedVersion = '2.0.0' + ExpectedPrerelease = '' + ExpectedFullVersion = 'v2.0.0' + } + @{ + Name = 'Auto-patch with no label produces release version' + LatestVersion = '1.0.1' + ReleaseType = 'Release' + AutoPatching = $true + IncrementalPrerelease = $false + VersionPrefix = 'v' + HeadRef = 'feat/test-autopatch' + Labels = @() + ExpectedCreateRelease = $true + ExpectedReleaseType = 'Release' + ExpectedVersion = '1.0.2' + ExpectedPrerelease = '' + ExpectedFullVersion = 'v1.0.2' + } + @{ + Name = 'Ignore label suppresses release, produces prerelease' + LatestVersion = '1.0.1' + ReleaseType = 'Release' + AutoPatching = $false + IncrementalPrerelease = $false + VersionPrefix = 'v' + HeadRef = 'feat/test-ignore' + Labels = @('patch', 'skip-release') + ExpectedCreateRelease = $false + ExpectedReleaseType = 'None' + ExpectedVersion = '1.0.2' + ExpectedPrerelease = 'feattestignore001' + ExpectedFullVersion = 'v1.0.2-feattestignore001' + } + @{ + Name = 'ReleaseType None produces prerelease with counter' + LatestVersion = '1.0.1' + ReleaseType = 'None' + AutoPatching = $false + IncrementalPrerelease = $false + VersionPrefix = 'v' + HeadRef = 'feat/test-none' + Labels = @('patch') + ExpectedCreateRelease = $false + ExpectedReleaseType = 'None' + ExpectedVersion = '1.0.2' + ExpectedPrerelease = 'feattestnone001' + ExpectedFullVersion = 'v1.0.2-feattestnone001' + } + @{ + Name = 'Prerelease type with incremental counter' + LatestVersion = '1.0.1' + ReleaseType = 'Prerelease' + AutoPatching = $false + IncrementalPrerelease = $true + VersionPrefix = 'v' + HeadRef = 'feat/add-prerelease-support' + Labels = @('minor') + ExpectedCreateRelease = $true + ExpectedReleaseType = 'Prerelease' + ExpectedVersion = '1.1.0' + ExpectedPrerelease = 'feataddprereleasesupport001' + ExpectedFullVersion = 'v1.1.0-feataddprereleasesupport001' + } + @{ + Name = 'No label and no AutoPatching falls back to prerelease' + LatestVersion = '1.0.1' + ReleaseType = 'Release' + AutoPatching = $false + IncrementalPrerelease = $false + VersionPrefix = 'v' + HeadRef = 'feat/no-label' + Labels = @() + ExpectedCreateRelease = $false + ExpectedReleaseType = 'None' + ExpectedVersion = '1.0.2' + ExpectedPrerelease = 'featnolabel001' + ExpectedFullVersion = 'v1.0.2-featnolabel001' + } + ) +} diff --git a/tests/Helpers.Tests.ps1 b/tests/Helpers.Tests.ps1 index 21ac9b0..fcf7a55 100644 --- a/tests/Helpers.Tests.ps1 +++ b/tests/Helpers.Tests.ps1 @@ -1,5 +1,8 @@ #Requires -Modules @{ ModuleName = 'Pester'; ModuleVersion = '5.0' } +# Load test data at script scope so it is available during Pester discovery (-ForEach) +$TestData = Import-PowerShellDataFile -Path "$PSScriptRoot/Helpers.Tests.Data.psd1" + BeforeAll { # Install PSSemVer for version handling if (-not (Get-Module -ListAvailable -Name PSSemVer)) { @@ -32,144 +35,7 @@ Describe 'Resolve-ReleaseDecision' { } } - Context '' -ForEach @( - @{ - Name = 'Patch label with Release type' - ReleaseType = 'Release' - AutoPatching = $false - HeadRef = 'feat/test-patch' - Labels = @('patch') - Expected = @{ - ShouldPublish = $true - CreateRelease = $true - CreatePrerelease = $false - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = 'feattestpatch' - } - } - @{ - Name = 'Minor label with Release type' - ReleaseType = 'Release' - AutoPatching = $false - HeadRef = 'feat/test-minor' - Labels = @('minor') - Expected = @{ - ShouldPublish = $true - CreateRelease = $true - CreatePrerelease = $false - MajorRelease = $false - MinorRelease = $true - PatchRelease = $false - HasVersionBump = $true - PrereleaseName = 'feattestminor' - } - } - @{ - Name = 'Major label with Release type' - ReleaseType = 'Release' - AutoPatching = $false - HeadRef = 'feat/test-major' - Labels = @('major') - Expected = @{ - ShouldPublish = $true - CreateRelease = $true - CreatePrerelease = $false - MajorRelease = $true - MinorRelease = $false - PatchRelease = $false - HasVersionBump = $true - PrereleaseName = 'feattestmajor' - } - } - @{ - Name = 'AutoPatching with no label' - ReleaseType = 'Release' - AutoPatching = $true - HeadRef = 'feat/test-autopatch' - Labels = @() - Expected = @{ - ShouldPublish = $true - CreateRelease = $true - CreatePrerelease = $false - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = 'feattestautopatch' - } - } - @{ - Name = 'Ignore label suppresses release' - ReleaseType = 'Release' - AutoPatching = $false - HeadRef = 'feat/test-ignore' - Labels = @('patch', 'skip-release') - Expected = @{ - ShouldPublish = $false - CreateRelease = $true - CreatePrerelease = $true - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = 'feattestignore' - } - } - @{ - Name = 'ReleaseType None produces prerelease' - ReleaseType = 'None' - AutoPatching = $false - HeadRef = 'feat/test-none' - Labels = @('patch') - Expected = @{ - ShouldPublish = $false - CreateRelease = $false - CreatePrerelease = $true - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = 'feattestnone' - } - } - @{ - Name = 'ReleaseType Prerelease with minor label' - ReleaseType = 'Prerelease' - AutoPatching = $false - HeadRef = 'feat/add-prerelease-support' - Labels = @('minor') - Expected = @{ - ShouldPublish = $true - CreateRelease = $false - CreatePrerelease = $true - MajorRelease = $false - MinorRelease = $true - PatchRelease = $false - HasVersionBump = $true - PrereleaseName = 'feataddprereleasesupport' - } - } - @{ - Name = 'No bump label and no AutoPatching falls back to prerelease' - ReleaseType = 'Release' - AutoPatching = $false - HeadRef = 'feat/no-label' - Labels = @() - Expected = @{ - ShouldPublish = $false - CreateRelease = $true - CreatePrerelease = $true - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = 'featnolabel' - } - } - ) { + Context '' -ForEach $TestData.ReleaseDecision { BeforeAll { $config = [PSCustomObject]@{ AutoPatching = $AutoPatching @@ -221,188 +87,7 @@ Describe 'Get-NextModuleVersion' { $emptyReleases = @([PSCustomObject]@{ tagName = 'v0.0.0'; isLatest = $false; isPrerelease = $false }) } - Context '' -ForEach @( - @{ - Name = 'Patch bump - Release' - LatestVersion = '1.0.1' - VersionPrefix = 'v' - IncrementalPrerelease = $false - DatePrereleaseFormat = '' - Decision = @{ - ShouldPublish = $true - CreateRelease = $true - CreatePrerelease = $false - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = 'feattestpatch' - } - ExpectedVersion = '1.0.2' - ExpectedPrerelease = '' - ExpectedPrefix = 'v' - } - @{ - Name = 'Minor bump - Release' - LatestVersion = '1.0.1' - VersionPrefix = 'v' - IncrementalPrerelease = $false - DatePrereleaseFormat = '' - Decision = @{ - ShouldPublish = $true - CreateRelease = $true - CreatePrerelease = $false - MajorRelease = $false - MinorRelease = $true - PatchRelease = $false - HasVersionBump = $true - PrereleaseName = 'feattestminor' - } - ExpectedVersion = '1.1.0' - ExpectedPrerelease = '' - ExpectedPrefix = 'v' - } - @{ - Name = 'Major bump - Release' - LatestVersion = '1.2.3' - VersionPrefix = 'v' - IncrementalPrerelease = $false - DatePrereleaseFormat = '' - Decision = @{ - ShouldPublish = $true - CreateRelease = $true - CreatePrerelease = $false - MajorRelease = $true - MinorRelease = $false - PatchRelease = $false - HasVersionBump = $true - PrereleaseName = 'feattestmajor' - } - ExpectedVersion = '2.0.0' - ExpectedPrerelease = '' - ExpectedPrefix = 'v' - } - @{ - Name = 'ReleaseType None - prerelease with incremental counter' - LatestVersion = '1.0.1' - VersionPrefix = 'v' - IncrementalPrerelease = $false - DatePrereleaseFormat = '' - Decision = @{ - ShouldPublish = $false - CreateRelease = $false - CreatePrerelease = $true - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = 'feattestnone' - } - ExpectedVersion = '1.0.2' - ExpectedPrerelease = 'feattestnone001' - ExpectedPrefix = 'v' - } - @{ - Name = 'Prerelease type with IncrementalPrerelease' - LatestVersion = '1.0.1' - VersionPrefix = 'v' - IncrementalPrerelease = $true - DatePrereleaseFormat = '' - Decision = @{ - ShouldPublish = $true - CreateRelease = $false - CreatePrerelease = $true - MajorRelease = $false - MinorRelease = $true - PatchRelease = $false - HasVersionBump = $true - PrereleaseName = 'feataddprereleasesupport' - } - ExpectedVersion = '1.1.0' - ExpectedPrerelease = 'feataddprereleasesupport001' - ExpectedPrefix = 'v' - } - @{ - Name = 'Ignore label falls back to prerelease with counter' - LatestVersion = '1.0.1' - VersionPrefix = 'v' - IncrementalPrerelease = $false - DatePrereleaseFormat = '' - Decision = @{ - ShouldPublish = $false - CreateRelease = $true - CreatePrerelease = $true - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = 'feattestignore' - } - ExpectedVersion = '1.0.2' - ExpectedPrerelease = 'feattestignore001' - ExpectedPrefix = 'v' - } - @{ - Name = 'No version prefix' - LatestVersion = '2.0.0' - VersionPrefix = '' - IncrementalPrerelease = $false - DatePrereleaseFormat = '' - Decision = @{ - ShouldPublish = $true - CreateRelease = $true - CreatePrerelease = $false - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = 'main' - } - ExpectedVersion = '2.0.1' - ExpectedPrerelease = '' - ExpectedPrefix = '' - } - @{ - Name = 'AutoPatch - Release with no label' - LatestVersion = '1.0.1' - VersionPrefix = 'v' - IncrementalPrerelease = $false - DatePrereleaseFormat = '' - Decision = @{ - ShouldPublish = $true - CreateRelease = $true - CreatePrerelease = $false - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = 'feattestautopatch' - } - ExpectedVersion = '1.0.2' - ExpectedPrerelease = '' - ExpectedPrefix = 'v' - } - @{ - Name = 'Prerelease without IncrementalPrerelease but ShouldPublish true' - LatestVersion = '1.0.0' - VersionPrefix = 'v' - IncrementalPrerelease = $false - DatePrereleaseFormat = '' - Decision = @{ - ShouldPublish = $true - CreateRelease = $false - CreatePrerelease = $true - MajorRelease = $false - MinorRelease = $false - PatchRelease = $true - HasVersionBump = $true - PrereleaseName = 'dev' - } - ExpectedVersion = '1.0.1' - ExpectedPrerelease = 'dev' - ExpectedPrefix = 'v' - } - ) { + Context '' -ForEach $TestData.NextModuleVersion { BeforeAll { $config = [PSCustomObject]@{ AutoPatching = $false @@ -442,128 +127,7 @@ Describe 'End-to-end: Resolve-ReleaseDecision + Get-NextModuleVersion' { $emptyReleases = @([PSCustomObject]@{ tagName = 'v0.0.0'; isLatest = $false; isPrerelease = $false }) } - Context '' -ForEach @( - @{ - Name = 'Patch bump produces release version' - LatestVersion = '1.0.1' - ReleaseType = 'Release' - AutoPatching = $false - IncrementalPrerelease = $false - VersionPrefix = 'v' - HeadRef = 'feat/test-patch' - Labels = @('patch') - ExpectedCreateRelease = $true - ExpectedReleaseType = 'Release' - ExpectedVersion = '1.0.2' - ExpectedPrerelease = '' - ExpectedFullVersion = 'v1.0.2' - } - @{ - Name = 'Minor bump produces release version' - LatestVersion = '1.0.1' - ReleaseType = 'Release' - AutoPatching = $false - IncrementalPrerelease = $false - VersionPrefix = 'v' - HeadRef = 'feat/test-minor' - Labels = @('minor') - ExpectedCreateRelease = $true - ExpectedReleaseType = 'Release' - ExpectedVersion = '1.1.0' - ExpectedPrerelease = '' - ExpectedFullVersion = 'v1.1.0' - } - @{ - Name = 'Major bump produces release version' - LatestVersion = '1.0.1' - ReleaseType = 'Release' - AutoPatching = $false - IncrementalPrerelease = $false - VersionPrefix = 'v' - HeadRef = 'feat/test-major' - Labels = @('major') - ExpectedCreateRelease = $true - ExpectedReleaseType = 'Release' - ExpectedVersion = '2.0.0' - ExpectedPrerelease = '' - ExpectedFullVersion = 'v2.0.0' - } - @{ - Name = 'Auto-patch with no label produces release version' - LatestVersion = '1.0.1' - ReleaseType = 'Release' - AutoPatching = $true - IncrementalPrerelease = $false - VersionPrefix = 'v' - HeadRef = 'feat/test-autopatch' - Labels = @() - ExpectedCreateRelease = $true - ExpectedReleaseType = 'Release' - ExpectedVersion = '1.0.2' - ExpectedPrerelease = '' - ExpectedFullVersion = 'v1.0.2' - } - @{ - Name = 'Ignore label suppresses release, produces prerelease' - LatestVersion = '1.0.1' - ReleaseType = 'Release' - AutoPatching = $false - IncrementalPrerelease = $false - VersionPrefix = 'v' - HeadRef = 'feat/test-ignore' - Labels = @('patch', 'skip-release') - ExpectedCreateRelease = $false - ExpectedReleaseType = 'None' - ExpectedVersion = '1.0.2' - ExpectedPrerelease = 'feattestignore001' - ExpectedFullVersion = 'v1.0.2-feattestignore001' - } - @{ - Name = 'ReleaseType None produces prerelease with counter' - LatestVersion = '1.0.1' - ReleaseType = 'None' - AutoPatching = $false - IncrementalPrerelease = $false - VersionPrefix = 'v' - HeadRef = 'feat/test-none' - Labels = @('patch') - ExpectedCreateRelease = $false - ExpectedReleaseType = 'None' - ExpectedVersion = '1.0.2' - ExpectedPrerelease = 'feattestnone001' - ExpectedFullVersion = 'v1.0.2-feattestnone001' - } - @{ - Name = 'Prerelease type with incremental counter' - LatestVersion = '1.0.1' - ReleaseType = 'Prerelease' - AutoPatching = $false - IncrementalPrerelease = $true - VersionPrefix = 'v' - HeadRef = 'feat/add-prerelease-support' - Labels = @('minor') - ExpectedCreateRelease = $true - ExpectedReleaseType = 'Prerelease' - ExpectedVersion = '1.1.0' - ExpectedPrerelease = 'feataddprereleasesupport001' - ExpectedFullVersion = 'v1.1.0-feataddprereleasesupport001' - } - @{ - Name = 'No label and no AutoPatching falls back to prerelease' - LatestVersion = '1.0.1' - ReleaseType = 'Release' - AutoPatching = $false - IncrementalPrerelease = $false - VersionPrefix = 'v' - HeadRef = 'feat/no-label' - Labels = @() - ExpectedCreateRelease = $false - ExpectedReleaseType = 'None' - ExpectedVersion = '1.0.2' - ExpectedPrerelease = 'featnolabel001' - ExpectedFullVersion = 'v1.0.2-featnolabel001' - } - ) { + Context '' -ForEach $TestData.EndToEnd { BeforeAll { $config = [PSCustomObject]@{ AutoPatching = $AutoPatching From 39fd8e01d54fcda9716ed4186f13dc8d2c21d299 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 21:33:40 +0200 Subject: [PATCH 13/19] chore: remove obsolete tests README.md file --- tests/README.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 tests/README.md diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index 43816d3..0000000 --- a/tests/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Placeholder for tests - -Location for tests of the action. From 05fc9528c843099a25e759537e6b9b0f44584246 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 21:36:48 +0200 Subject: [PATCH 14/19] ci: set Output_Verbosity to Detailed for Pester test output --- .github/workflows/Action-Test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index b774821..c0d4450 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -32,6 +32,7 @@ jobs: with: Path: ./tests Run_Path: ./scripts + Output_Verbosity: Detailed TestResult_TestSuiteName: Resolve-PSModuleVersion - name: Check test outcome From 66452f0880ac4cbf653b09ce060238dfb8a6de01 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 21:45:20 +0200 Subject: [PATCH 15/19] ci: pin PSModule/Invoke-Pester to SHA --- .github/workflows/Action-Test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index c0d4450..04409d8 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -28,7 +28,7 @@ jobs: - name: Run Pester tests id: pester - uses: PSModule/Invoke-Pester@v4 + uses: PSModule/Invoke-Pester@266d1cf2532f572470b7c4463fa1072f2bfe4455 # v4.2.5 with: Path: ./tests Run_Path: ./scripts From 07fc879d753db28336c5b5c987d1f03658daf446 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 21:47:22 +0200 Subject: [PATCH 16/19] style: fix PSScriptAnalyzer alignment and suppression warnings --- tests/Helpers.Tests.Data.psd1 | 58 +++++++++++++++++------------------ tests/Helpers.Tests.ps1 | 8 +++++ 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/tests/Helpers.Tests.Data.psd1 b/tests/Helpers.Tests.Data.psd1 index ad7aca2..a7e0802 100644 --- a/tests/Helpers.Tests.Data.psd1 +++ b/tests/Helpers.Tests.Data.psd1 @@ -1,5 +1,5 @@ @{ - ReleaseDecision = @( + ReleaseDecision = @( @{ Name = 'Patch label with Release type' ReleaseType = 'Release' @@ -145,6 +145,9 @@ VersionPrefix = 'v' IncrementalPrerelease = $false DatePrereleaseFormat = '' + ExpectedVersion = '1.0.2' + ExpectedPrerelease = '' + ExpectedPrefix = 'v' Decision = @{ ShouldPublish = $true CreateRelease = $true @@ -155,9 +158,6 @@ HasVersionBump = $true PrereleaseName = 'feattestpatch' } - ExpectedVersion = '1.0.2' - ExpectedPrerelease = '' - ExpectedPrefix = 'v' } @{ Name = 'Minor bump - Release' @@ -165,6 +165,9 @@ VersionPrefix = 'v' IncrementalPrerelease = $false DatePrereleaseFormat = '' + ExpectedVersion = '1.1.0' + ExpectedPrerelease = '' + ExpectedPrefix = 'v' Decision = @{ ShouldPublish = $true CreateRelease = $true @@ -175,9 +178,6 @@ HasVersionBump = $true PrereleaseName = 'feattestminor' } - ExpectedVersion = '1.1.0' - ExpectedPrerelease = '' - ExpectedPrefix = 'v' } @{ Name = 'Major bump - Release' @@ -185,6 +185,9 @@ VersionPrefix = 'v' IncrementalPrerelease = $false DatePrereleaseFormat = '' + ExpectedVersion = '2.0.0' + ExpectedPrerelease = '' + ExpectedPrefix = 'v' Decision = @{ ShouldPublish = $true CreateRelease = $true @@ -195,9 +198,6 @@ HasVersionBump = $true PrereleaseName = 'feattestmajor' } - ExpectedVersion = '2.0.0' - ExpectedPrerelease = '' - ExpectedPrefix = 'v' } @{ Name = 'ReleaseType None - prerelease with incremental counter' @@ -205,6 +205,9 @@ VersionPrefix = 'v' IncrementalPrerelease = $false DatePrereleaseFormat = '' + ExpectedVersion = '1.0.2' + ExpectedPrerelease = 'feattestnone001' + ExpectedPrefix = 'v' Decision = @{ ShouldPublish = $false CreateRelease = $false @@ -215,9 +218,6 @@ HasVersionBump = $true PrereleaseName = 'feattestnone' } - ExpectedVersion = '1.0.2' - ExpectedPrerelease = 'feattestnone001' - ExpectedPrefix = 'v' } @{ Name = 'Prerelease type with IncrementalPrerelease' @@ -225,6 +225,9 @@ VersionPrefix = 'v' IncrementalPrerelease = $true DatePrereleaseFormat = '' + ExpectedVersion = '1.1.0' + ExpectedPrerelease = 'feataddprereleasesupport001' + ExpectedPrefix = 'v' Decision = @{ ShouldPublish = $true CreateRelease = $false @@ -235,9 +238,6 @@ HasVersionBump = $true PrereleaseName = 'feataddprereleasesupport' } - ExpectedVersion = '1.1.0' - ExpectedPrerelease = 'feataddprereleasesupport001' - ExpectedPrefix = 'v' } @{ Name = 'Ignore label falls back to prerelease with counter' @@ -245,6 +245,9 @@ VersionPrefix = 'v' IncrementalPrerelease = $false DatePrereleaseFormat = '' + ExpectedVersion = '1.0.2' + ExpectedPrerelease = 'feattestignore001' + ExpectedPrefix = 'v' Decision = @{ ShouldPublish = $false CreateRelease = $true @@ -255,9 +258,6 @@ HasVersionBump = $true PrereleaseName = 'feattestignore' } - ExpectedVersion = '1.0.2' - ExpectedPrerelease = 'feattestignore001' - ExpectedPrefix = 'v' } @{ Name = 'No version prefix' @@ -265,6 +265,9 @@ VersionPrefix = '' IncrementalPrerelease = $false DatePrereleaseFormat = '' + ExpectedVersion = '2.0.1' + ExpectedPrerelease = '' + ExpectedPrefix = '' Decision = @{ ShouldPublish = $true CreateRelease = $true @@ -275,9 +278,6 @@ HasVersionBump = $true PrereleaseName = 'main' } - ExpectedVersion = '2.0.1' - ExpectedPrerelease = '' - ExpectedPrefix = '' } @{ Name = 'AutoPatch - Release with no label' @@ -285,6 +285,9 @@ VersionPrefix = 'v' IncrementalPrerelease = $false DatePrereleaseFormat = '' + ExpectedVersion = '1.0.2' + ExpectedPrerelease = '' + ExpectedPrefix = 'v' Decision = @{ ShouldPublish = $true CreateRelease = $true @@ -295,9 +298,6 @@ HasVersionBump = $true PrereleaseName = 'feattestautopatch' } - ExpectedVersion = '1.0.2' - ExpectedPrerelease = '' - ExpectedPrefix = 'v' } @{ Name = 'Prerelease without IncrementalPrerelease but ShouldPublish true' @@ -305,6 +305,9 @@ VersionPrefix = 'v' IncrementalPrerelease = $false DatePrereleaseFormat = '' + ExpectedVersion = '1.0.1' + ExpectedPrerelease = 'dev' + ExpectedPrefix = 'v' Decision = @{ ShouldPublish = $true CreateRelease = $false @@ -315,13 +318,10 @@ HasVersionBump = $true PrereleaseName = 'dev' } - ExpectedVersion = '1.0.1' - ExpectedPrerelease = 'dev' - ExpectedPrefix = 'v' } ) - EndToEnd = @( + EndToEnd = @( @{ Name = 'Patch bump produces release version' LatestVersion = '1.0.1' diff --git a/tests/Helpers.Tests.ps1 b/tests/Helpers.Tests.ps1 index fcf7a55..55d1901 100644 --- a/tests/Helpers.Tests.ps1 +++ b/tests/Helpers.Tests.ps1 @@ -1,5 +1,13 @@ #Requires -Modules @{ ModuleName = 'Pester'; ModuleVersion = '5.0' } +[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', + Justification = 'Variables are used across Pester BeforeAll/It blocks.')] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', + Justification = 'Parameters in LogGroup mock are required by the caller signature.')] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSProvideCommentHelp', '', + Justification = 'LogGroup is a test helper mock, not a public function.')] +param() + # Load test data at script scope so it is available during Pester discovery (-ForEach) $TestData = Import-PowerShellDataFile -Path "$PSScriptRoot/Helpers.Tests.Data.psd1" From 49b4694ef188dc1e223c49b9b380ee47a5c5523f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 22:00:01 +0200 Subject: [PATCH 17/19] Address review feedback: fix help typo, rename test field, correct comment --- scripts/Helpers.psm1 | 2 +- tests/Helpers.Tests.Data.psd1 | 18 +++++++++--------- tests/Helpers.Tests.ps1 | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/scripts/Helpers.psm1 b/scripts/Helpers.psm1 index 6216af1..5a70e97 100644 --- a/scripts/Helpers.psm1 +++ b/scripts/Helpers.psm1 @@ -282,7 +282,7 @@ function Get-GitHubRelease { Array of release objects. .EXAMPLE - $releases = Get-GitHubReleases + $releases = Get-GitHubRelease #> [CmdletBinding()] [OutputType([array])] diff --git a/tests/Helpers.Tests.Data.psd1 b/tests/Helpers.Tests.Data.psd1 index a7e0802..0e1e2d5 100644 --- a/tests/Helpers.Tests.Data.psd1 +++ b/tests/Helpers.Tests.Data.psd1 @@ -1,4 +1,4 @@ -@{ +@{ ReleaseDecision = @( @{ Name = 'Patch label with Release type' @@ -331,7 +331,7 @@ VersionPrefix = 'v' HeadRef = 'feat/test-patch' Labels = @('patch') - ExpectedCreateRelease = $true + ExpectedShouldPublish = $true ExpectedReleaseType = 'Release' ExpectedVersion = '1.0.2' ExpectedPrerelease = '' @@ -346,7 +346,7 @@ VersionPrefix = 'v' HeadRef = 'feat/test-minor' Labels = @('minor') - ExpectedCreateRelease = $true + ExpectedShouldPublish = $true ExpectedReleaseType = 'Release' ExpectedVersion = '1.1.0' ExpectedPrerelease = '' @@ -361,7 +361,7 @@ VersionPrefix = 'v' HeadRef = 'feat/test-major' Labels = @('major') - ExpectedCreateRelease = $true + ExpectedShouldPublish = $true ExpectedReleaseType = 'Release' ExpectedVersion = '2.0.0' ExpectedPrerelease = '' @@ -376,7 +376,7 @@ VersionPrefix = 'v' HeadRef = 'feat/test-autopatch' Labels = @() - ExpectedCreateRelease = $true + ExpectedShouldPublish = $true ExpectedReleaseType = 'Release' ExpectedVersion = '1.0.2' ExpectedPrerelease = '' @@ -391,7 +391,7 @@ VersionPrefix = 'v' HeadRef = 'feat/test-ignore' Labels = @('patch', 'skip-release') - ExpectedCreateRelease = $false + ExpectedShouldPublish = $false ExpectedReleaseType = 'None' ExpectedVersion = '1.0.2' ExpectedPrerelease = 'feattestignore001' @@ -406,7 +406,7 @@ VersionPrefix = 'v' HeadRef = 'feat/test-none' Labels = @('patch') - ExpectedCreateRelease = $false + ExpectedShouldPublish = $false ExpectedReleaseType = 'None' ExpectedVersion = '1.0.2' ExpectedPrerelease = 'feattestnone001' @@ -421,7 +421,7 @@ VersionPrefix = 'v' HeadRef = 'feat/add-prerelease-support' Labels = @('minor') - ExpectedCreateRelease = $true + ExpectedShouldPublish = $true ExpectedReleaseType = 'Prerelease' ExpectedVersion = '1.1.0' ExpectedPrerelease = 'feataddprereleasesupport001' @@ -436,7 +436,7 @@ VersionPrefix = 'v' HeadRef = 'feat/no-label' Labels = @() - ExpectedCreateRelease = $false + ExpectedShouldPublish = $false ExpectedReleaseType = 'None' ExpectedVersion = '1.0.2' ExpectedPrerelease = 'featnolabel001' diff --git a/tests/Helpers.Tests.ps1 b/tests/Helpers.Tests.ps1 index 55d1901..4ec0a93 100644 --- a/tests/Helpers.Tests.ps1 +++ b/tests/Helpers.Tests.ps1 @@ -18,7 +18,7 @@ BeforeAll { } Import-Module -Name PSSemVer -Force - # Mock the Helpers module (LogGroup, Add-Content for GITHUB_OUTPUT) + # Mock LogGroup so module functions execute their blocks without console decoration function LogGroup { param([string]$Name, [scriptblock]$ScriptBlock) & $ScriptBlock @@ -165,8 +165,8 @@ Describe 'End-to-end: Resolve-ReleaseDecision + Get-NextModuleVersion' { } } - It 'CreateRelease is ' { - $decision.ShouldPublish | Should -Be $ExpectedCreateRelease + It 'ShouldPublish is ' { + $decision.ShouldPublish | Should -Be $ExpectedShouldPublish } It 'ReleaseType is ' { $resolvedReleaseType | Should -Be $ExpectedReleaseType From 930390d9eaa2d688bd93dd91e1927261f93e7cf3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 27 May 2026 23:13:29 +0200 Subject: [PATCH 18/19] test: mock Find-PSResource to eliminate PSGallery network dependency --- tests/Helpers.Tests.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Helpers.Tests.ps1 b/tests/Helpers.Tests.ps1 index 4ec0a93..364c521 100644 --- a/tests/Helpers.Tests.ps1 +++ b/tests/Helpers.Tests.ps1 @@ -92,6 +92,7 @@ Describe 'Resolve-ReleaseDecision' { Describe 'Get-NextModuleVersion' { BeforeAll { + Mock -CommandName Find-PSResource -ModuleName Helpers -MockWith { @() } $emptyReleases = @([PSCustomObject]@{ tagName = 'v0.0.0'; isLatest = $false; isPrerelease = $false }) } @@ -132,6 +133,7 @@ Describe 'Get-NextModuleVersion' { Describe 'End-to-end: Resolve-ReleaseDecision + Get-NextModuleVersion' { BeforeAll { + Mock -CommandName Find-PSResource -ModuleName Helpers -MockWith { @() } $emptyReleases = @([PSCustomObject]@{ tagName = 'v0.0.0'; isLatest = $false; isPrerelease = $false }) } From 462fdccbc8e59d6310d9bf8d4f860f7c16ca4764 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 8 Jul 2026 00:52:36 +0200 Subject: [PATCH 19/19] fix: rename script module to ResolveVersion to avoid Helpers collision The self-contained script module was named 'Helpers', which collides with the framework Helpers module (installed by PSModule/Install-PSModuleHelpers) that is also loaded in the Invoke-Pester test session. Pester's 'Mock -ModuleName Helpers' cannot disambiguate two modules sharing a name, so every test mocking Find-PSResource failed with 'Multiple script or manifest modules named Helpers are currently loaded'. Renaming the module (and its test files) to the unique name ResolveVersion removes the ambiguity. No runtime logic changed. --- scripts/{Helpers.psm1 => ResolveVersion.psm1} | 0 scripts/main.ps1 | 2 +- ...ers.Tests.Data.psd1 => ResolveVersion.Tests.Data.psd1} | 0 tests/{Helpers.Tests.ps1 => ResolveVersion.Tests.ps1} | 8 ++++---- 4 files changed, 5 insertions(+), 5 deletions(-) rename scripts/{Helpers.psm1 => ResolveVersion.psm1} (100%) rename tests/{Helpers.Tests.Data.psd1 => ResolveVersion.Tests.Data.psd1} (100%) rename tests/{Helpers.Tests.ps1 => ResolveVersion.Tests.ps1} (95%) diff --git a/scripts/Helpers.psm1 b/scripts/ResolveVersion.psm1 similarity index 100% rename from scripts/Helpers.psm1 rename to scripts/ResolveVersion.psm1 diff --git a/scripts/main.ps1 b/scripts/main.ps1 index b22dd6a..2408024 100644 --- a/scripts/main.ps1 +++ b/scripts/main.ps1 @@ -4,7 +4,7 @@ param() $PSStyle.OutputRendering = 'Ansi' Import-Module -Name 'Helpers' -Force -Import-Module -Name "$PSScriptRoot/Helpers.psm1" -Force +Import-Module -Name "$PSScriptRoot/ResolveVersion.psm1" -Force $actionInput = Read-ActionInput $config = Get-PublishConfiguration -SettingsJson $actionInput.SettingsJson diff --git a/tests/Helpers.Tests.Data.psd1 b/tests/ResolveVersion.Tests.Data.psd1 similarity index 100% rename from tests/Helpers.Tests.Data.psd1 rename to tests/ResolveVersion.Tests.Data.psd1 diff --git a/tests/Helpers.Tests.ps1 b/tests/ResolveVersion.Tests.ps1 similarity index 95% rename from tests/Helpers.Tests.ps1 rename to tests/ResolveVersion.Tests.ps1 index 364c521..2c28603 100644 --- a/tests/Helpers.Tests.ps1 +++ b/tests/ResolveVersion.Tests.ps1 @@ -9,7 +9,7 @@ param() # Load test data at script scope so it is available during Pester discovery (-ForEach) -$TestData = Import-PowerShellDataFile -Path "$PSScriptRoot/Helpers.Tests.Data.psd1" +$TestData = Import-PowerShellDataFile -Path "$PSScriptRoot/ResolveVersion.Tests.Data.psd1" BeforeAll { # Install PSSemVer for version handling @@ -25,7 +25,7 @@ BeforeAll { } # Import the module under test - Import-Module -Name "$PSScriptRoot/../scripts/Helpers.psm1" -Force + Import-Module -Name "$PSScriptRoot/../scripts/ResolveVersion.psm1" -Force } Describe 'Resolve-ReleaseDecision' { @@ -92,7 +92,7 @@ Describe 'Resolve-ReleaseDecision' { Describe 'Get-NextModuleVersion' { BeforeAll { - Mock -CommandName Find-PSResource -ModuleName Helpers -MockWith { @() } + Mock -CommandName Find-PSResource -ModuleName ResolveVersion -MockWith { @() } $emptyReleases = @([PSCustomObject]@{ tagName = 'v0.0.0'; isLatest = $false; isPrerelease = $false }) } @@ -133,7 +133,7 @@ Describe 'Get-NextModuleVersion' { Describe 'End-to-end: Resolve-ReleaseDecision + Get-NextModuleVersion' { BeforeAll { - Mock -CommandName Find-PSResource -ModuleName Helpers -MockWith { @() } + Mock -CommandName Find-PSResource -ModuleName ResolveVersion -MockWith { @() } $emptyReleases = @([PSCustomObject]@{ tagName = 'v0.0.0'; isLatest = $false; isPrerelease = $false }) }