From e7c128a7bba46c32b7cee195235eb710c85f9761 Mon Sep 17 00:00:00 2001 From: MariusStorhaug Date: Fri, 22 May 2026 21:32:16 +0200 Subject: [PATCH 01/10] Implement Resolve-PSModuleVersion action --- README.md | 73 +++++++++++- action.yml | 67 +++++++---- scripts/main.ps1 | 294 ++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 391 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index d560186..07b23a2 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,82 @@ -# Template-Action +# Resolve-PSModuleVersion -A template repository for GitHub Actions +A GitHub Action that resolves the next module version from settings, PR labels, GitHub releases, and the PowerShell Gallery. + +This action is the single decision point for module versioning. It runs in the **Plan** phase of a workflow, before the module is +built, so that `Build-PSModule` can stamp the resolved version into the manifest. The bytes that are tested are then the bytes +that ship to the PowerShell Gallery and to GitHub Releases. ## Usage +This action is consumed by [`PSModule/Process-PSModule`](https://github.com/PSModule/Process-PSModule) but can be used directly. +It expects to run on a `pull_request` event and consumes the JSON `Settings` output from +[`PSModule/Get-PSModuleSettings`](https://github.com/PSModule/Get-PSModuleSettings). + ### Inputs -### Secrets +| Name | Required | Default | Description | +| ---- | -------- | ------- | ----------- | +| `Settings` | yes | | The full settings object as a JSON string (output of `Get-PSModuleSettings`). | +| `Name` | no | `${repository name}` | The module name. When empty, the repository name is used. | +| `WorkingDirectory` | no | `.` | Working directory for the script. | +| `Debug` | no | `false` | Enable debug output. | +| `Verbose` | no | `false` | Enable verbose output. | +| `Version` | no | | Pin a specific version of the GitHub helper module. | +| `Prerelease` | no | `false` | Allow prerelease versions of the GitHub helper module. | + +The action reads the following keys from `Settings.Publish.Module`: + +- `ReleaseType` (`Release` / `Prerelease` / `None`) +- `AutoPatching` +- `IncrementalPrerelease` +- `DatePrereleaseFormat` +- `VersionPrefix` +- `MajorLabels`, `MinorLabels`, `PatchLabels`, `IgnoreLabels` (comma-separated) ### Outputs +| Name | Description | +| ---- | ----------- | +| `Version` | The `Major.Minor.Patch` portion of the resolved version (for example `1.4.0`). | +| `Prerelease` | The prerelease tag, empty when not a prerelease. | +| `FullVersion` | The full version string including `VersionPrefix` and prerelease tag (for example `v1.4.0-mybranch001`). | +| `ReleaseType` | The resolved release type. `Release`, `Prerelease`, or `None` when no version bump label is present. | +| `CreateRelease` | `true` when a release or prerelease should actually be created from this run. | + +### Permissions + +The action needs `contents: read` (for `actions/checkout`) and `pull-requests: read` to read PR labels. The +`GH_TOKEN` environment variable must be set so `gh release list` can query GitHub releases. + ### Example ```yaml -Example here +- name: Resolve module version + id: resolve + uses: PSModule/Resolve-PSModuleVersion@v1 + env: + GH_TOKEN: ${{ github.token }} + with: + Settings: ${{ steps.settings.outputs.Settings }} + +- name: Build module + uses: PSModule/Build-PSModule@v5 + with: + Version: ${{ steps.resolve.outputs.Version }} + Prerelease: ${{ steps.resolve.outputs.Prerelease }} ``` + +## How it works + +1. Loads the resolved `Settings` JSON and the `pull_request` event payload. +2. Validates `ReleaseType` and applies `IgnoreLabels` overrides. +3. Picks the bump type from PR labels: `MajorLabels` > `MinorLabels` > (`PatchLabels` or `AutoPatching`). +4. Reads the latest version from GitHub Releases (`gh release list`) and the PowerShell Gallery (`Find-PSResource`), + takes the higher of the two as the baseline. +5. Bumps the baseline according to the resolved bump type. +6. For prereleases, appends the sanitized branch name, optionally a `DatePrereleaseFormat` timestamp, and an + incremental counter calculated from existing prereleases on the same baseline + branch. +7. Emits `Version`, `Prerelease`, `FullVersion`, `ReleaseType`, and `CreateRelease` as step outputs. + +When `ReleaseType` is `None`, when an `IgnoreLabels` label is present, or when no version bump label is found +(and `AutoPatching` is disabled), `CreateRelease` is `false` and the version outputs are empty strings. diff --git a/action.yml b/action.yml index fb42d0b..c87c353 100644 --- a/action.yml +++ b/action.yml @@ -1,15 +1,21 @@ -name: Template-Action -description: A template action for GitHub Actions using PowerShell +name: Resolve-PSModuleVersion +description: Resolves the next module version from settings, PR labels, GitHub releases, and the PowerShell Gallery. author: PSModule branding: - icon: upload-cloud + icon: tag color: white inputs: - Subject: - description: The subject to greet + Settings: + description: The complete settings object as a JSON string (output of Get-PSModuleSettings). + required: true + Name: + description: Name of the module. When empty, the repository name is used. required: false - default: World + WorkingDirectory: + description: The working directory where the script will run from. + required: false + default: '.' Debug: description: Enable debug output. required: false @@ -22,26 +28,43 @@ inputs: description: Specifies the version of the GitHub module to be installed. The value must be an exact version. required: false Prerelease: - description: Allow prerelease versions if available. + description: Allow prerelease versions of the GitHub module if available. required: false default: 'false' - WorkingDirectory: - description: The working directory where the script will run from. - required: false - default: ${{ github.workspace }} + +outputs: + Version: + description: The Major.Minor.Patch portion of the resolved version. + value: ${{ steps.resolve.outputs.Version }} + Prerelease: + description: The prerelease tag, empty when not a prerelease. + value: ${{ steps.resolve.outputs.Prerelease }} + FullVersion: + description: The full version string including version prefix and prerelease tag (for example v1.4.0-alpha001). + value: ${{ steps.resolve.outputs.FullVersion }} + ReleaseType: + description: The resolved release type - Release, Prerelease, or None. + value: ${{ steps.resolve.outputs.ReleaseType }} + CreateRelease: + description: 'true when a release or prerelease should be created from this run.' + value: ${{ steps.resolve.outputs.CreateRelease }} runs: using: composite steps: - - name: Template-Action - uses: PSModule/GitHub-Script@0097f3bbe3f413f3b577b9bcc600727b0ca3201a # v1.7.10 + - name: Install-PSModuleHelpers + uses: PSModule/Install-PSModuleHelpers@ed79b6e3aa8c9cd3d30ab2bf02ea6bd4687b9c74 # v1.0.7 + + - name: Install PSSemVer + shell: pwsh + run: | + Install-PSResource -Name PSSemVer -Repository PSGallery -TrustRepository + + - name: Resolve module version + id: resolve + shell: pwsh + working-directory: ${{ inputs.WorkingDirectory }} env: - PSMOUDLE_TEMPLATE_ACTION_INPUT_Subject: ${{ inputs.Subject }} - with: - Name: Template-Action - Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} - Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} - WorkingDirectory: ${{ inputs.WorkingDirectory }} - Script: ${{ github.action_path }}/scripts/main.ps1 + PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_Settings: ${{ inputs.Settings }} + PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_Name: ${{ inputs.Name }} + run: ${{ github.action_path }}/scripts/main.ps1 diff --git a/scripts/main.ps1 b/scripts/main.ps1 index 480b20a..3bd67ba 100644 --- a/scripts/main.ps1 +++ b/scripts/main.ps1 @@ -1,24 +1,284 @@ -#Requires -Modules GitHub - +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseDeclaredVarsMoreThanAssignments', 'prereleaseName', + Justification = 'Variable is used in script blocks.' +)] [CmdletBinding()] -param( - [Parameter()] - [string] $Subject = $env:PSMOUDLE_TEMPLATE_ACTION_INPUT_Subject -) - -begin { - $scriptName = $MyInvocation.MyCommand.Name - Write-Debug "[$scriptName] - Start" +param() + +$PSStyle.OutputRendering = 'Ansi' + +Import-Module -Name 'Helpers' -Force + +LogGroup 'Load inputs' { + $env:GITHUB_REPOSITORY_NAME = $env:GITHUB_REPOSITORY -replace '.+/' + + $name = if ([string]::IsNullOrEmpty($env:PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_Name)) { + $env:GITHUB_REPOSITORY_NAME + } else { + $env:PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_Name + } + Write-Host "Module name: [$name]" + + $settingsJson = $env:PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_Settings + if ([string]::IsNullOrWhiteSpace($settingsJson)) { + Write-Error 'Settings input is required.' + exit 1 + } + $settings = $settingsJson | ConvertFrom-Json + $publishModule = $settings.Publish.Module +} + +LogGroup 'Resolve configuration' { + $autoPatching = [bool]$publishModule.AutoPatching + $incrementalPrerelease = [bool]$publishModule.IncrementalPrerelease + $datePrereleaseFormat = [string]$publishModule.DatePrereleaseFormat + $versionPrefix = [string]$publishModule.VersionPrefix + $releaseType = [string]$publishModule.ReleaseType + $ignoreLabels = (([string]$publishModule.IgnoreLabels) -split ',') | ForEach-Object { $_.Trim() } | Where-Object { $_ } + $majorLabels = (([string]$publishModule.MajorLabels) -split ',') | ForEach-Object { $_.Trim() } | Where-Object { $_ } + $minorLabels = (([string]$publishModule.MinorLabels) -split ',') | ForEach-Object { $_.Trim() } | Where-Object { $_ } + $patchLabels = (([string]$publishModule.PatchLabels) -split ',') | ForEach-Object { $_.Trim() } | Where-Object { $_ } + + Write-Host '-------------------------------------------------' + [pscustomobject]@{ + AutoPatching = $autoPatching + IncrementalPrerelease = $incrementalPrerelease + DatePrereleaseFormat = $datePrereleaseFormat + VersionPrefix = $versionPrefix + ReleaseType = $releaseType + IgnoreLabels = $ignoreLabels -join ', ' + MajorLabels = $majorLabels -join ', ' + MinorLabels = $minorLabels -join ', ' + PatchLabels = $patchLabels -join ', ' + } | Format-List | Out-String + Write-Host '-------------------------------------------------' +} + +LogGroup 'Event information' { + $githubEventJson = Get-Content $env:GITHUB_EVENT_PATH + $githubEvent = $githubEventJson | ConvertFrom-Json + $pull_request = $githubEvent.pull_request + if (-not $pull_request) { + throw 'GitHub event does not contain pull_request data. This action must be run from a pull_request event.' + } + $prHeadRef = $pull_request.head.ref + $labels = @() + $labels += $pull_request.labels.name + + Write-Host '-------------------------------------------------' + [PSCustomObject]@{ + PRHeadRef = $prHeadRef + Labels = $labels -join ', ' + } | Format-List | Out-String + Write-Host '-------------------------------------------------' +} + +LogGroup 'Determine release configuration' { + $prereleaseName = $prHeadRef -replace '[^a-zA-Z0-9]' + + $validReleaseTypes = @('Release', 'Prerelease', 'None') + if ([string]::IsNullOrWhiteSpace($releaseType)) { + Write-Error "Settings.Publish.Module.ReleaseType is required. Valid values are: $($validReleaseTypes -join ', ')" + exit 1 + } + if ($releaseType -notin $validReleaseTypes) { + Write-Error "Invalid ReleaseType: [$releaseType]. Valid values are: $($validReleaseTypes -join ', ')" + exit 1 + } + + $createRelease = $releaseType -eq 'Release' + $createPrerelease = $releaseType -eq 'Prerelease' + $shouldPublish = $createRelease -or $createPrerelease + + $ignoreRelease = ($labels | Where-Object { $ignoreLabels -contains $_ }).Count -gt 0 + if ($ignoreRelease -and $shouldPublish) { + Write-Host 'Ignoring release creation due to ignore label.' + $shouldPublish = $false + } + + $majorRelease = $false + $minorRelease = $false + $patchRelease = $false + $hasVersionBump = $false + + if ($shouldPublish) { + $majorRelease = ($labels | Where-Object { $majorLabels -contains $_ }).Count -gt 0 + $minorRelease = ($labels | Where-Object { $minorLabels -contains $_ }).Count -gt 0 -and -not $majorRelease + $patchRelease = ( + (($labels | Where-Object { $patchLabels -contains $_ }).Count -gt 0) -or $autoPatching + ) -and -not $majorRelease -and -not $minorRelease + + $hasVersionBump = $majorRelease -or $minorRelease -or $patchRelease + if (-not $hasVersionBump) { + Write-Host 'No version bump label found and AutoPatching is disabled. No release will be created.' + $shouldPublish = $false + } + } + + Write-Host '-------------------------------------------------' + [PSCustomObject]@{ + ReleaseType = $releaseType + ShouldPublish = $shouldPublish + CreateRelease = $createRelease + CreatePrerelease = $createPrerelease + Major = $majorRelease + Minor = $minorRelease + Patch = $patchRelease + } | Format-List | Out-String + Write-Host '-------------------------------------------------' } -process { - try { - Write-Output "Hello, $Subject!" - } catch { - throw $_ +$newVersion = $null +$releases = @() + +if ($shouldPublish) { + LogGroup 'Get releases - GitHub' { + $releases = gh release list --json 'createdAt,isDraft,isLatest,isPrerelease,name,publishedAt,tagName' | ConvertFrom-Json + if ($LASTEXITCODE -ne 0) { + Write-Error 'Failed to list releases for the repo.' + exit $LASTEXITCODE + } + Write-Host '-------------------------------------------------' + $releases | Select-Object -Property name, isPrerelease, isLatest, publishedAt | Format-Table | Out-String + Write-Host '-------------------------------------------------' + } + + LogGroup 'Get latest version - GitHub' { + $latestRelease = $releases | Where-Object { $_.isLatest -eq $true } + $ghReleaseVersionString = $latestRelease.tagName + if (-not [string]::IsNullOrEmpty($ghReleaseVersionString)) { + $ghReleaseVersion = New-PSSemVer -Version $ghReleaseVersionString + } else { + Write-Warning "Could not find the latest GitHub release. Using '0.0.0'." + $ghReleaseVersion = New-PSSemVer -Version '0.0.0' + } + Write-Host "GitHub version: [$($ghReleaseVersion.ToString())]" + } + + LogGroup 'Get latest version - PSGallery' { + $count = 5 + $delay = 10 + $latest = $null + for ($i = 1; $i -le $count; $i++) { + try { + Write-Host "Finding module [$name] in the PowerShell Gallery." + $latest = Find-PSResource -Name $name -Repository PSGallery -Verbose:$false + Write-Host "$($latest | Format-Table | Out-String)" + break + } catch { + if ($i -eq $count) { + Write-Warning "Failed to find the module [$name] in the PowerShell Gallery." + Write-Warning $_.Exception.Message + } + Start-Sleep -Seconds $delay + } + } + if ($latest.Version) { + $psGalleryVersion = New-PSSemVer -Version ($latest.Version).ToString() + } else { + Write-Warning "Could not find module online. Using '0.0.0'." + $psGalleryVersion = New-PSSemVer -Version '0.0.0' + } + Write-Host "PSGallery version: [$($psGalleryVersion.ToString())]" + } + + LogGroup 'Latest version' { + $latestVersion = New-PSSemVer -Version ($psGalleryVersion, $ghReleaseVersion | Sort-Object -Descending | Select-Object -First 1) + Write-Host "Latest version: [$($latestVersion.ToString())]" + } + + LogGroup 'Calculate new version' { + $newVersion = New-PSSemVer -Version $latestVersion + $newVersion.Prefix = $versionPrefix + if ($majorRelease) { + Write-Host 'Incrementing major version.' + $newVersion.BumpMajor() + } elseif ($minorRelease) { + Write-Host 'Incrementing minor version.' + $newVersion.BumpMinor() + } elseif ($patchRelease) { + Write-Host 'Incrementing patch version.' + $newVersion.BumpPatch() + } + Write-Host "Partial new version: [$newVersion]" + + if ($createPrerelease -and $hasVersionBump) { + Write-Host "Adding a prerelease tag using the branch name [$prereleaseName]." + $newVersion.Prerelease = $prereleaseName + + if (-not [string]::IsNullOrEmpty($datePrereleaseFormat)) { + Write-Host "Using date-based prerelease format: [$datePrereleaseFormat]." + $newVersion.Prerelease += "$(Get-Date -Format $datePrereleaseFormat)" + } + + if ($incrementalPrerelease) { + $newVersionString = "$($newVersion.Major).$($newVersion.Minor).$($newVersion.Patch)" + $params = @{ + Name = $name + Version = '*' + Prerelease = $true + Repository = 'PSGallery' + Verbose = $false + ErrorAction = 'SilentlyContinue' + } + $psGalleryPrereleases = Find-PSResource @params | + Where-Object { $_.Version -like $newVersionString } | + Where-Object { $_.Prerelease -like "$prereleaseName*" } + $latestPSGalleryPrerelease = $psGalleryPrereleases.Prerelease | ForEach-Object { + [int]($_ -replace $prereleaseName) + } | Sort-Object | Select-Object -Last 1 + Write-Host "PSGallery prerelease: [$latestPSGalleryPrerelease]" + + $ghPrereleases = $releases | + Where-Object { $_.tagName -like "*$newVersionString*" } | + Where-Object { $_.tagName -like "*$prereleaseName*" } + $latestGHPrereleases = $ghPrereleases.tagName | ForEach-Object { + $number = $_ -replace '\.' + $number = ($number -split $prereleaseName, 2)[-1] + [int]$number + } | Sort-Object | Select-Object -Last 1 + Write-Host "GitHub prerelease: [$latestGHPrereleases]" + + if ($null -eq $latestPSGalleryPrerelease) { $latestPSGalleryPrerelease = 0 } + if ($null -eq $latestGHPrereleases) { $latestGHPrereleases = 0 } + + $latestPrereleaseNumber = [Math]::Max($latestPSGalleryPrerelease, $latestGHPrereleases) + 1 + $latestPrereleaseNumber = ([string]$latestPrereleaseNumber).PadLeft(3, '0') + $newVersion.Prerelease += $latestPrereleaseNumber + } + } + + Write-Host "New version: [$($newVersion.ToString())]" } } -end { - Write-Debug "[$scriptName] - End" +LogGroup 'Emit outputs' { + $versionString = '' + $prereleaseString = '' + $fullVersionString = '' + $resolvedReleaseType = $releaseType + if ($newVersion) { + $versionString = "$($newVersion.Major).$($newVersion.Minor).$($newVersion.Patch)" + $prereleaseString = [string]$newVersion.Prerelease + $fullVersionString = $newVersion.ToString() + } + if (-not $shouldPublish) { + $resolvedReleaseType = 'None' + } + + Add-Content -Path $env:GITHUB_OUTPUT -Value "Version=$versionString" + Add-Content -Path $env:GITHUB_OUTPUT -Value "Prerelease=$prereleaseString" + Add-Content -Path $env:GITHUB_OUTPUT -Value "FullVersion=$fullVersionString" + Add-Content -Path $env:GITHUB_OUTPUT -Value "ReleaseType=$resolvedReleaseType" + Add-Content -Path $env:GITHUB_OUTPUT -Value "CreateRelease=$($shouldPublish.ToString().ToLower())" + + Write-Host '-------------------------------------------------' + [PSCustomObject]@{ + Version = $versionString + Prerelease = $prereleaseString + FullVersion = $fullVersionString + ReleaseType = $resolvedReleaseType + CreateRelease = $shouldPublish + } | Format-List | Out-String + Write-Host '-------------------------------------------------' } From 6d0500c8893860cf261787b90cf4cbd1d2e0f153 Mon Sep 17 00:00:00 2001 From: MariusStorhaug Date: Fri, 22 May 2026 21:45:50 +0200 Subject: [PATCH 02/10] Replace detailed README with framework redirect --- README.md | 81 +------------------------------------------------------ 1 file changed, 1 insertion(+), 80 deletions(-) diff --git a/README.md b/README.md index 07b23a2..82dc431 100644 --- a/README.md +++ b/README.md @@ -1,82 +1,3 @@ # Resolve-PSModuleVersion -A GitHub Action that resolves the next module version from settings, PR labels, GitHub releases, and the PowerShell Gallery. - -This action is the single decision point for module versioning. It runs in the **Plan** phase of a workflow, before the module is -built, so that `Build-PSModule` can stamp the resolved version into the manifest. The bytes that are tested are then the bytes -that ship to the PowerShell Gallery and to GitHub Releases. - -## Usage - -This action is consumed by [`PSModule/Process-PSModule`](https://github.com/PSModule/Process-PSModule) but can be used directly. -It expects to run on a `pull_request` event and consumes the JSON `Settings` output from -[`PSModule/Get-PSModuleSettings`](https://github.com/PSModule/Get-PSModuleSettings). - -### Inputs - -| Name | Required | Default | Description | -| ---- | -------- | ------- | ----------- | -| `Settings` | yes | | The full settings object as a JSON string (output of `Get-PSModuleSettings`). | -| `Name` | no | `${repository name}` | The module name. When empty, the repository name is used. | -| `WorkingDirectory` | no | `.` | Working directory for the script. | -| `Debug` | no | `false` | Enable debug output. | -| `Verbose` | no | `false` | Enable verbose output. | -| `Version` | no | | Pin a specific version of the GitHub helper module. | -| `Prerelease` | no | `false` | Allow prerelease versions of the GitHub helper module. | - -The action reads the following keys from `Settings.Publish.Module`: - -- `ReleaseType` (`Release` / `Prerelease` / `None`) -- `AutoPatching` -- `IncrementalPrerelease` -- `DatePrereleaseFormat` -- `VersionPrefix` -- `MajorLabels`, `MinorLabels`, `PatchLabels`, `IgnoreLabels` (comma-separated) - -### Outputs - -| Name | Description | -| ---- | ----------- | -| `Version` | The `Major.Minor.Patch` portion of the resolved version (for example `1.4.0`). | -| `Prerelease` | The prerelease tag, empty when not a prerelease. | -| `FullVersion` | The full version string including `VersionPrefix` and prerelease tag (for example `v1.4.0-mybranch001`). | -| `ReleaseType` | The resolved release type. `Release`, `Prerelease`, or `None` when no version bump label is present. | -| `CreateRelease` | `true` when a release or prerelease should actually be created from this run. | - -### Permissions - -The action needs `contents: read` (for `actions/checkout`) and `pull-requests: read` to read PR labels. The -`GH_TOKEN` environment variable must be set so `gh release list` can query GitHub releases. - -### Example - -```yaml -- name: Resolve module version - id: resolve - uses: PSModule/Resolve-PSModuleVersion@v1 - env: - GH_TOKEN: ${{ github.token }} - with: - Settings: ${{ steps.settings.outputs.Settings }} - -- name: Build module - uses: PSModule/Build-PSModule@v5 - with: - Version: ${{ steps.resolve.outputs.Version }} - Prerelease: ${{ steps.resolve.outputs.Prerelease }} -``` - -## How it works - -1. Loads the resolved `Settings` JSON and the `pull_request` event payload. -2. Validates `ReleaseType` and applies `IgnoreLabels` overrides. -3. Picks the bump type from PR labels: `MajorLabels` > `MinorLabels` > (`PatchLabels` or `AutoPatching`). -4. Reads the latest version from GitHub Releases (`gh release list`) and the PowerShell Gallery (`Find-PSResource`), - takes the higher of the two as the baseline. -5. Bumps the baseline according to the resolved bump type. -6. For prereleases, appends the sanitized branch name, optionally a `DatePrereleaseFormat` timestamp, and an - incremental counter calculated from existing prereleases on the same baseline + branch. -7. Emits `Version`, `Prerelease`, `FullVersion`, `ReleaseType`, and `CreateRelease` as step outputs. - -When `ReleaseType` is `None`, when an `IgnoreLabels` label is present, or when no version bump label is found -(and `AutoPatching` is disabled), `CreateRelease` is `false` and the version outputs are empty strings. +This GitHub Action is a part of the [PSModule framework](https://github.com/PSModule). From 165e5ac52aa0d328f95c36928279be9e4768b020 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 22 May 2026 22:43:24 +0200 Subject: [PATCH 03/10] Fix CI failures: replace [Basic] test job with scenario-based jobs; add PSAvoidUsingWriteHost exclusion; suppress publishModule unused-var warning --- .../linters/.powershell-psscriptanalyzer.psd1 | 1 + .github/workflows/Action-Test.yml | 392 +++++++++++++++++- scripts/main.ps1 | 4 + 3 files changed, 392 insertions(+), 5 deletions(-) diff --git a/.github/linters/.powershell-psscriptanalyzer.psd1 b/.github/linters/.powershell-psscriptanalyzer.psd1 index 09cc3d0..f1b546d 100644 --- a/.github/linters/.powershell-psscriptanalyzer.psd1 +++ b/.github/linters/.powershell-psscriptanalyzer.psd1 @@ -50,6 +50,7 @@ } } ExcludeRules = @( + 'PSAvoidUsingWriteHost', # Write-Host is acceptable in GitHub Actions runners. 'PSMissingModuleManifestField', # This rule is not applicable until the module is built. 'PSUseToExportFieldsInManifest' ) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index 97129a3..a477ccf 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -17,17 +17,399 @@ permissions: pull-requests: read jobs: - ActionTestBasic: - name: Action-Test - [Basic] + ActionTest-PatchBump: + name: Action-Test - [Patch bump] runs-on: ubuntu-latest steps: - # Need to check out as part of the test, as its a local action - name: Checkout repo uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - name: Action-Test + - 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": "" + } + } + } + + - name: Verify - Patch bump + shell: pwsh + run: | + $createRelease = '${{ steps.resolve.outputs.CreateRelease }}' + $version = '${{ steps.resolve.outputs.Version }}' + $releaseType = '${{ steps.resolve.outputs.ReleaseType }}' + $fullVersion = '${{ steps.resolve.outputs.FullVersion }}' + + if ($createRelease -ne 'true') { + Write-Error "Expected CreateRelease='true', got '$createRelease'" + exit 1 + } + if ([string]::IsNullOrEmpty($version)) { + Write-Error 'Expected a non-empty Version' + exit 1 + } + if ($releaseType -ne 'Release') { + Write-Error "Expected ReleaseType='Release', got '$releaseType'" + exit 1 + } + + Write-Host "Version: $version" + Write-Host "FullVersion: $fullVersion" + Write-Host "ReleaseType: $releaseType" + Write-Host "CreateRelease: $createRelease" + + 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": "" + } + } + } + + - name: Verify - Minor bump + shell: pwsh + run: | + $createRelease = '${{ steps.resolve.outputs.CreateRelease }}' + $version = '${{ steps.resolve.outputs.Version }}' + $releaseType = '${{ steps.resolve.outputs.ReleaseType }}' + $fullVersion = '${{ steps.resolve.outputs.FullVersion }}' + + if ($createRelease -ne 'true') { + Write-Error "Expected CreateRelease='true', got '$createRelease'" + exit 1 + } + if ([string]::IsNullOrEmpty($version)) { + Write-Error 'Expected a non-empty Version' + exit 1 + } + if ($releaseType -ne 'Release') { + Write-Error "Expected ReleaseType='Release', got '$releaseType'" + exit 1 + } + + Write-Host "Version: $version" + Write-Host "FullVersion: $fullVersion" + Write-Host "ReleaseType: $releaseType" + Write-Host "CreateRelease: $createRelease" + + 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": "" + } + } + } + + - name: Verify - Major bump + shell: pwsh + run: | + $createRelease = '${{ steps.resolve.outputs.CreateRelease }}' + $version = '${{ steps.resolve.outputs.Version }}' + $releaseType = '${{ steps.resolve.outputs.ReleaseType }}' + $fullVersion = '${{ steps.resolve.outputs.FullVersion }}' + + if ($createRelease -ne 'true') { + Write-Error "Expected CreateRelease='true', got '$createRelease'" + exit 1 + } + if ([string]::IsNullOrEmpty($version)) { + Write-Error 'Expected a non-empty Version' + exit 1 + } + if ($releaseType -ne 'Release') { + Write-Error "Expected ReleaseType='Release', got '$releaseType'" + exit 1 + } + + Write-Host "Version: $version" + Write-Host "FullVersion: $fullVersion" + Write-Host "ReleaseType: $releaseType" + Write-Host "CreateRelease: $createRelease" + + 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: - Subject: PSModule + Settings: | + { + "Publish": { + "Module": { + "ReleaseType": "Release", + "AutoPatching": true, + "VersionPrefix": "v", + "MajorLabels": "major", + "MinorLabels": "minor", + "PatchLabels": "patch", + "IgnoreLabels": "" + } + } + } + + - name: Verify - Auto-patch + shell: pwsh + run: | + $createRelease = '${{ steps.resolve.outputs.CreateRelease }}' + $version = '${{ steps.resolve.outputs.Version }}' + $releaseType = '${{ steps.resolve.outputs.ReleaseType }}' + $fullVersion = '${{ steps.resolve.outputs.FullVersion }}' + + if ($createRelease -ne 'true') { + Write-Error "Expected CreateRelease='true', got '$createRelease'" + exit 1 + } + if ([string]::IsNullOrEmpty($version)) { + Write-Error 'Expected a non-empty Version' + exit 1 + } + if ($releaseType -ne 'Release') { + Write-Error "Expected ReleaseType='Release', got '$releaseType'" + exit 1 + } + + Write-Host "Version: $version" + Write-Host "FullVersion: $fullVersion" + Write-Host "ReleaseType: $releaseType" + Write-Host "CreateRelease: $createRelease" + + ActionTest-IgnoreLabel: + name: Action-Test - [Ignore label] + 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-ignore' } + labels = @( + @{ name = 'patch' } + @{ name = 'skip-release' } + ) + } + } | 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": "skip-release" + } + } + } + + - name: Verify - Ignore label + shell: pwsh + run: | + $createRelease = '${{ steps.resolve.outputs.CreateRelease }}' + $releaseType = '${{ steps.resolve.outputs.ReleaseType }}' + + if ($createRelease -ne 'false') { + Write-Error "Expected CreateRelease='false', got '$createRelease'" + exit 1 + } + if ($releaseType -ne 'None') { + Write-Error "Expected ReleaseType='None', got '$releaseType'" + exit 1 + } + + Write-Host "ReleaseType: $releaseType" + Write-Host "CreateRelease: $createRelease" + + 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": "" + } + } + } + + - name: Verify - None release type + shell: pwsh + run: | + $createRelease = '${{ steps.resolve.outputs.CreateRelease }}' + $version = '${{ steps.resolve.outputs.Version }}' + $releaseType = '${{ steps.resolve.outputs.ReleaseType }}' + + if ($createRelease -ne 'false') { + Write-Error "Expected CreateRelease='false', got '$createRelease'" + exit 1 + } + if (-not [string]::IsNullOrEmpty($version)) { + Write-Error "Expected empty Version, got '$version'" + exit 1 + } + if ($releaseType -ne 'None') { + Write-Error "Expected ReleaseType='None', got '$releaseType'" + exit 1 + } + + Write-Host "Version: $version" + Write-Host "ReleaseType: $releaseType" + Write-Host "CreateRelease: $createRelease" diff --git a/scripts/main.ps1 b/scripts/main.ps1 index 3bd67ba..d9e232d 100644 --- a/scripts/main.ps1 +++ b/scripts/main.ps1 @@ -2,6 +2,10 @@ 'PSUseDeclaredVarsMoreThanAssignments', 'prereleaseName', Justification = 'Variable is used in script blocks.' )] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseDeclaredVarsMoreThanAssignments', 'publishModule', + Justification = 'Variable is used in script blocks.' +)] [CmdletBinding()] param() From 52924edfaadfd87f8ef31e81e53c77bb21966f4f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 22 May 2026 23:02:55 +0200 Subject: [PATCH 04/10] Fix CI: add GH_TOKEN to test jobs and fix zizmor template-injection finding --- .github/workflows/Action-Test.yml | 81 ++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 22 deletions(-) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index a477ccf..eda020b 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -1,6 +1,6 @@ name: Action-Test -run-name: "Action-Test - [${{ github.event.pull_request.title }} #${{ github.event.pull_request.number }}] by @${{ github.actor }}" +run-name: 'Action-Test - [${{ github.event.pull_request.title }} #${{ github.event.pull_request.number }}] by @${{ github.actor }}' on: workflow_dispatch: @@ -43,6 +43,8 @@ jobs: - name: Resolve-PSModuleVersion id: resolve uses: ./ + env: + GH_TOKEN: ${{ github.token }} with: Settings: | { @@ -61,11 +63,16 @@ jobs: - name: Verify - Patch bump shell: pwsh + env: + 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: | - $createRelease = '${{ steps.resolve.outputs.CreateRelease }}' - $version = '${{ steps.resolve.outputs.Version }}' - $releaseType = '${{ steps.resolve.outputs.ReleaseType }}' - $fullVersion = '${{ steps.resolve.outputs.FullVersion }}' + $createRelease = $env:RESOLVE_CREATE_RELEASE + $version = $env:RESOLVE_VERSION + $releaseType = $env:RESOLVE_RELEASE_TYPE + $fullVersion = $env:RESOLVE_FULL_VERSION if ($createRelease -ne 'true') { Write-Error "Expected CreateRelease='true', got '$createRelease'" @@ -111,6 +118,8 @@ jobs: - name: Resolve-PSModuleVersion id: resolve uses: ./ + env: + GH_TOKEN: ${{ github.token }} with: Settings: | { @@ -129,11 +138,16 @@ jobs: - name: Verify - Minor bump shell: pwsh + env: + 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: | - $createRelease = '${{ steps.resolve.outputs.CreateRelease }}' - $version = '${{ steps.resolve.outputs.Version }}' - $releaseType = '${{ steps.resolve.outputs.ReleaseType }}' - $fullVersion = '${{ steps.resolve.outputs.FullVersion }}' + $createRelease = $env:RESOLVE_CREATE_RELEASE + $version = $env:RESOLVE_VERSION + $releaseType = $env:RESOLVE_RELEASE_TYPE + $fullVersion = $env:RESOLVE_FULL_VERSION if ($createRelease -ne 'true') { Write-Error "Expected CreateRelease='true', got '$createRelease'" @@ -179,6 +193,8 @@ jobs: - name: Resolve-PSModuleVersion id: resolve uses: ./ + env: + GH_TOKEN: ${{ github.token }} with: Settings: | { @@ -197,11 +213,16 @@ jobs: - name: Verify - Major bump shell: pwsh + env: + 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: | - $createRelease = '${{ steps.resolve.outputs.CreateRelease }}' - $version = '${{ steps.resolve.outputs.Version }}' - $releaseType = '${{ steps.resolve.outputs.ReleaseType }}' - $fullVersion = '${{ steps.resolve.outputs.FullVersion }}' + $createRelease = $env:RESOLVE_CREATE_RELEASE + $version = $env:RESOLVE_VERSION + $releaseType = $env:RESOLVE_RELEASE_TYPE + $fullVersion = $env:RESOLVE_FULL_VERSION if ($createRelease -ne 'true') { Write-Error "Expected CreateRelease='true', got '$createRelease'" @@ -245,6 +266,8 @@ jobs: - name: Resolve-PSModuleVersion id: resolve uses: ./ + env: + GH_TOKEN: ${{ github.token }} with: Settings: | { @@ -263,11 +286,16 @@ jobs: - name: Verify - Auto-patch shell: pwsh + env: + 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: | - $createRelease = '${{ steps.resolve.outputs.CreateRelease }}' - $version = '${{ steps.resolve.outputs.Version }}' - $releaseType = '${{ steps.resolve.outputs.ReleaseType }}' - $fullVersion = '${{ steps.resolve.outputs.FullVersion }}' + $createRelease = $env:RESOLVE_CREATE_RELEASE + $version = $env:RESOLVE_VERSION + $releaseType = $env:RESOLVE_RELEASE_TYPE + $fullVersion = $env:RESOLVE_FULL_VERSION if ($createRelease -ne 'true') { Write-Error "Expected CreateRelease='true', got '$createRelease'" @@ -314,6 +342,8 @@ jobs: - name: Resolve-PSModuleVersion id: resolve uses: ./ + env: + GH_TOKEN: ${{ github.token }} with: Settings: | { @@ -332,9 +362,12 @@ jobs: - name: Verify - Ignore label shell: pwsh + env: + RESOLVE_CREATE_RELEASE: ${{ steps.resolve.outputs.CreateRelease }} + RESOLVE_RELEASE_TYPE: ${{ steps.resolve.outputs.ReleaseType }} run: | - $createRelease = '${{ steps.resolve.outputs.CreateRelease }}' - $releaseType = '${{ steps.resolve.outputs.ReleaseType }}' + $createRelease = $env:RESOLVE_CREATE_RELEASE + $releaseType = $env:RESOLVE_RELEASE_TYPE if ($createRelease -ne 'false') { Write-Error "Expected CreateRelease='false', got '$createRelease'" @@ -392,10 +425,14 @@ jobs: - name: Verify - None release type shell: pwsh + env: + RESOLVE_CREATE_RELEASE: ${{ steps.resolve.outputs.CreateRelease }} + RESOLVE_VERSION: ${{ steps.resolve.outputs.Version }} + RESOLVE_RELEASE_TYPE: ${{ steps.resolve.outputs.ReleaseType }} run: | - $createRelease = '${{ steps.resolve.outputs.CreateRelease }}' - $version = '${{ steps.resolve.outputs.Version }}' - $releaseType = '${{ steps.resolve.outputs.ReleaseType }}' + $createRelease = $env:RESOLVE_CREATE_RELEASE + $version = $env:RESOLVE_VERSION + $releaseType = $env:RESOLVE_RELEASE_TYPE if ($createRelease -ne 'false') { Write-Error "Expected CreateRelease='false', got '$createRelease'" From 53101724512d7b40a2f763e22eb6b6e8d1af8ede Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 22 May 2026 23:09:34 +0200 Subject: [PATCH 05/10] Move github.action_path expansion to env var in composite action step --- action.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index c87c353..5937bfa 100644 --- a/action.yml +++ b/action.yml @@ -67,4 +67,5 @@ runs: env: PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_Settings: ${{ inputs.Settings }} PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_Name: ${{ inputs.Name }} - run: ${{ github.action_path }}/scripts/main.ps1 + PSMODULE_ACTION_PATH: ${{ github.action_path }} + run: & "$env:PSMODULE_ACTION_PATH/scripts/main.ps1" From 02c84316231e46c462f06c833b3766ab83364b2a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 22 May 2026 23:28:50 +0200 Subject: [PATCH 06/10] Fix action.yml YAML syntax: use block scalar for run containing ampersand --- action.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 5937bfa..b662569 100644 --- a/action.yml +++ b/action.yml @@ -68,4 +68,5 @@ runs: PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_Settings: ${{ inputs.Settings }} PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_Name: ${{ inputs.Name }} PSMODULE_ACTION_PATH: ${{ github.action_path }} - run: & "$env:PSMODULE_ACTION_PATH/scripts/main.ps1" + run: | + & "$env:PSMODULE_ACTION_PATH/scripts/main.ps1" From 5460f125a6941e7ebbf6de24cb9ac2a5f0cdc4f9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 22 May 2026 23:48:55 +0200 Subject: [PATCH 07/10] Fix [Ignore label] test: write fake event to unique path and pass GITHUB_EVENT_PATH explicitly --- .github/workflows/Action-Test.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index eda020b..ccf9c09 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -336,14 +336,15 @@ jobs: ) } } | 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 + $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: ./ env: GH_TOKEN: ${{ github.token }} + GITHUB_EVENT_PATH: ${{ runner.temp }}/fake-event.json with: Settings: | { From d35dd9e5472bbfc9cde623c70923f11b322c8f1a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 22 May 2026 23:55:06 +0200 Subject: [PATCH 08/10] Fix [Ignore label] test: add EventPath input to action.yml to pass fake event into inner composite step --- .github/workflows/Action-Test.yml | 2 +- action.yml | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index ccf9c09..dd1d93d 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -344,7 +344,6 @@ jobs: uses: ./ env: GH_TOKEN: ${{ github.token }} - GITHUB_EVENT_PATH: ${{ runner.temp }}/fake-event.json with: Settings: | { @@ -360,6 +359,7 @@ jobs: } } } + EventPath: ${{ runner.temp }}/fake-event.json - name: Verify - Ignore label shell: pwsh diff --git a/action.yml b/action.yml index b662569..436ae81 100644 --- a/action.yml +++ b/action.yml @@ -31,6 +31,10 @@ inputs: description: Allow prerelease versions of the GitHub module if available. required: false default: 'false' + EventPath: + description: Path to the GitHub event JSON file. Defaults to the standard GitHub event path. Override for testing. + required: false + default: '' outputs: Version: @@ -68,5 +72,6 @@ runs: PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_Settings: ${{ inputs.Settings }} PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_Name: ${{ inputs.Name }} PSMODULE_ACTION_PATH: ${{ github.action_path }} + GITHUB_EVENT_PATH: ${{ inputs.EventPath || github.event_path }} run: | & "$env:PSMODULE_ACTION_PATH/scripts/main.ps1" From 0b0fedc41ad96fcb3ebd10484f13967e1cb69486 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 23 May 2026 00:00:58 +0200 Subject: [PATCH 09/10] Fix [Ignore label] test: add EventJson input so tests can pass event data without relying on event file --- .github/workflows/Action-Test.yml | 1 + action.yml | 5 +++++ scripts/main.ps1 | 9 +++++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index dd1d93d..71fc1d7 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -360,6 +360,7 @@ jobs: } } EventPath: ${{ runner.temp }}/fake-event.json + EventJson: '{"pull_request":{"head":{"ref":"feat/test-ignore"},"labels":[{"name":"patch"},{"name":"skip-release"}]}}' - name: Verify - Ignore label shell: pwsh diff --git a/action.yml b/action.yml index 436ae81..4507b68 100644 --- a/action.yml +++ b/action.yml @@ -35,6 +35,10 @@ inputs: description: Path to the GitHub event JSON file. Defaults to the standard GitHub event path. Override for testing. required: false default: '' + EventJson: + description: GitHub event payload as a JSON string. When set, overrides reading from the event file. Use for testing. + required: false + default: '' outputs: Version: @@ -71,6 +75,7 @@ runs: env: PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_Settings: ${{ inputs.Settings }} PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_Name: ${{ inputs.Name }} + PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_EventJson: ${{ inputs.EventJson }} PSMODULE_ACTION_PATH: ${{ github.action_path }} GITHUB_EVENT_PATH: ${{ inputs.EventPath || github.event_path }} run: | diff --git a/scripts/main.ps1 b/scripts/main.ps1 index d9e232d..f7c7bdc 100644 --- a/scripts/main.ps1 +++ b/scripts/main.ps1 @@ -59,8 +59,13 @@ LogGroup 'Resolve configuration' { } LogGroup 'Event information' { - $githubEventJson = Get-Content $env:GITHUB_EVENT_PATH - $githubEvent = $githubEventJson | ConvertFrom-Json + $eventJsonInput = $env:PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_EventJson + if (-not [string]::IsNullOrWhiteSpace($eventJsonInput)) { + $githubEvent = $eventJsonInput | ConvertFrom-Json + } else { + $githubEventJson = Get-Content $env:GITHUB_EVENT_PATH + $githubEvent = $githubEventJson | ConvertFrom-Json + } $pull_request = $githubEvent.pull_request if (-not $pull_request) { throw 'GitHub event does not contain pull_request data. This action must be run from a pull_request event.' From dfd02dbd7baeb1d4c45e97f7145b6566b7bd2d2b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 23 May 2026 01:10:27 +0200 Subject: [PATCH 10/10] Fix action.yml template leftovers and prerelease counter overflow - Remove unused Version/Prerelease inputs (template leftovers, collide by name with Version/Prerelease outputs) - Fix PSGallery version filter: replace string -like with component comparison so 4-part versions (e.g. 1.2.3.0) match correctly - Fix PSGallery and GitHub prerelease counter casts from [int] to [long] to prevent Int32 overflow when DatePrereleaseFormat produces date-prefixed counter strings (e.g. 20260523001) --- action.yml | 7 ------- scripts/main.ps1 | 6 +++--- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/action.yml b/action.yml index 4507b68..c2843ea 100644 --- a/action.yml +++ b/action.yml @@ -24,13 +24,6 @@ inputs: description: Enable verbose output. required: false default: 'false' - Version: - description: Specifies the version of the GitHub module to be installed. The value must be an exact version. - required: false - Prerelease: - description: Allow prerelease versions of the GitHub module if available. - required: false - default: 'false' EventPath: description: Path to the GitHub event JSON file. Defaults to the standard GitHub event path. Override for testing. required: false diff --git a/scripts/main.ps1 b/scripts/main.ps1 index f7c7bdc..60f0e18 100644 --- a/scripts/main.ps1 +++ b/scripts/main.ps1 @@ -231,10 +231,10 @@ if ($shouldPublish) { ErrorAction = 'SilentlyContinue' } $psGalleryPrereleases = Find-PSResource @params | - Where-Object { $_.Version -like $newVersionString } | + Where-Object { "$($_.Version.Major).$($_.Version.Minor).$($_.Version.Build)" -eq $newVersionString } | Where-Object { $_.Prerelease -like "$prereleaseName*" } $latestPSGalleryPrerelease = $psGalleryPrereleases.Prerelease | ForEach-Object { - [int]($_ -replace $prereleaseName) + [long]($_ -replace $prereleaseName) } | Sort-Object | Select-Object -Last 1 Write-Host "PSGallery prerelease: [$latestPSGalleryPrerelease]" @@ -244,7 +244,7 @@ if ($shouldPublish) { $latestGHPrereleases = $ghPrereleases.tagName | ForEach-Object { $number = $_ -replace '\.' $number = ($number -split $prereleaseName, 2)[-1] - [int]$number + [long]$number } | Sort-Object | Select-Object -Last 1 Write-Host "GitHub prerelease: [$latestGHPrereleases]"