From 49e6aae6b61351de175647527bd5c2fd8651bdbf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 May 2026 08:03:31 +0000 Subject: [PATCH 1/3] Bump PSModule/Invoke-Pester from 4.2.4 to 5.1.0 Invoke-Pester v5.0.0 repurposed the Version and Prerelease inputs to select the Pester module version and renamed the GitHub bootstrap-module controls to GitHubVersion and GitHubPrerelease. Remap the action's Version and Prerelease inputs (which select the GitHub module) to GitHubVersion and GitHubPrerelease to preserve their documented behavior. --- action.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index 8759594..13749b1 100644 --- a/action.yml +++ b/action.yml @@ -262,15 +262,15 @@ runs: Script: ${{ github.action_path }}/src/main.ps1 - name: Invoke-Pester - uses: PSModule/Invoke-Pester@abddf7bef0d0614d7ca322036af6a06ee0fb4d44 # v4.2.4 + uses: PSModule/Invoke-Pester@4ff33199141fdf22568990b6107fe3148ae93a1c # v5.1.0 id: test env: SettingsFilePath: ${{ fromJson(steps.paths.outputs.result).SettingsFilePath }} with: Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} + GitHubPrerelease: ${{ inputs.Prerelease }} + GitHubVersion: ${{ inputs.Version }} Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} WorkingDirectory: ${{ inputs.WorkingDirectory }} TestResult_TestSuiteName: ${{ inputs.TestResult_TestSuiteName }} Path: ${{ github.action_path }}/src/tests/PSScriptAnalyzer From 342f68b21d695b94875cd0fe7d99ac7ca055c70f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 10 Jul 2026 12:01:43 +0200 Subject: [PATCH 2/3] Split version/prerelease into Pester and GitHub inputs Add PesterVersion/PesterPrerelease and rename Version/Prerelease to GitHubVersion/GitHubPrerelease so Pester and GitHub module versions can be controlled independently and trickle down to the Invoke-Pester and GitHub-Script steps. --- README.md | 6 ++++-- action.yml | 29 +++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 37dfb24..08173ab 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,10 @@ customize rule selection, severity filtering, and custom rule inclusion. | `SettingsFilePath` | The path to the settings file. | false | `.github/linters/.powershell-psscriptanalyzer.psd1` | | `Debug` | Enable debug output. | false | `'false'` | | `Verbose` | Enable verbose output. | false | `'false'` | -| `Version` | Specifies the exact version of the GitHub module to install. | false | | -| `Prerelease` | Allow prerelease versions if available. | false | `'false'` | +| `PesterVersion` | Specifies the version of the Pester module to install (NuGet range). | false | | +| `PesterPrerelease` | Allow prerelease versions of the Pester module if available. | false | `'false'` | +| `GitHubVersion` | Specifies the version of the GitHub module to install (NuGet range). | false | | +| `GitHubPrerelease` | Allow prerelease versions of the GitHub module if available. | false | `'false'` | | `WorkingDirectory` | The working directory where the script runs. | false | `'.'` | | `ReportAsJson` | Output generated reports in JSON format in addition to the configured format. | false | `'true'` | | `Notice_Mode` | Controls when to show notices for test completion. | false | `'Failed'` | diff --git a/action.yml b/action.yml index 13749b1..d619da5 100644 --- a/action.yml +++ b/action.yml @@ -21,11 +21,22 @@ 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. + PesterVersion: + description: | + Specifies the version of the Pester module to install, using NuGet version-range syntax (for example '[6.0.0,7.0.0)'). + When empty, the latest available version is installed. + required: false + PesterPrerelease: + description: Allow prerelease versions of the Pester module if available. + required: false + default: 'false' + GitHubVersion: + description: | + Specifies the version of the GitHub module to install, using NuGet version-range syntax (for example '[1.2.0, 2.0.0)'). + When empty, the latest available version is installed. required: false - Prerelease: - description: Allow prerelease versions if available. + GitHubPrerelease: + description: Allow prerelease versions of the GitHub module if available. required: false default: 'false' WorkingDirectory: @@ -255,9 +266,9 @@ runs: PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_SettingsFilePath: ${{ inputs.SettingsFilePath }} with: Debug: ${{ inputs.Debug }} - Prerelease: ${{ inputs.Prerelease }} + Prerelease: ${{ inputs.GitHubPrerelease }} Verbose: ${{ inputs.Verbose }} - Version: ${{ inputs.Version }} + Version: ${{ inputs.GitHubVersion }} WorkingDirectory: ${{ inputs.WorkingDirectory }} Script: ${{ github.action_path }}/src/main.ps1 @@ -268,9 +279,11 @@ runs: SettingsFilePath: ${{ fromJson(steps.paths.outputs.result).SettingsFilePath }} with: Debug: ${{ inputs.Debug }} - GitHubPrerelease: ${{ inputs.Prerelease }} - GitHubVersion: ${{ inputs.Version }} + GitHubPrerelease: ${{ inputs.GitHubPrerelease }} + GitHubVersion: ${{ inputs.GitHubVersion }} + Prerelease: ${{ inputs.PesterPrerelease }} Verbose: ${{ inputs.Verbose }} + Version: ${{ inputs.PesterVersion }} WorkingDirectory: ${{ inputs.WorkingDirectory }} TestResult_TestSuiteName: ${{ inputs.TestResult_TestSuiteName }} Path: ${{ github.action_path }}/src/tests/PSScriptAnalyzer From 6239329093766b68edeff4159277905adba714ff Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 11 Jul 2026 12:46:40 +0200 Subject: [PATCH 3/3] Provision the selected PSScriptAnalyzer version via Version/Prerelease Version/Prerelease now control the PSScriptAnalyzer module (the action's namesake). A bundled prescript installs the chosen version, removes any other PSScriptAnalyzer version from the session, and imports the chosen version -Global so the tests use it instead of the runner's preinstalled copy. --- README.md | 2 + action.yml | 12 +++++ src/Install-PSScriptAnalyzer.ps1 | 75 ++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 src/Install-PSScriptAnalyzer.ps1 diff --git a/README.md b/README.md index 08173ab..27f0017 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ customize rule selection, severity filtering, and custom rule inclusion. | `SettingsFilePath` | The path to the settings file. | false | `.github/linters/.powershell-psscriptanalyzer.psd1` | | `Debug` | Enable debug output. | false | `'false'` | | `Verbose` | Enable verbose output. | false | `'false'` | +| `Version` | Specifies the version of the PSScriptAnalyzer module to install (NuGet range). | false | | +| `Prerelease` | Allow prerelease versions of the PSScriptAnalyzer module if available. | false | `'false'` | | `PesterVersion` | Specifies the version of the Pester module to install (NuGet range). | false | | | `PesterPrerelease` | Allow prerelease versions of the Pester module if available. | false | `'false'` | | `GitHubVersion` | Specifies the version of the GitHub module to install (NuGet range). | false | | diff --git a/action.yml b/action.yml index d619da5..4efa4b1 100644 --- a/action.yml +++ b/action.yml @@ -21,6 +21,15 @@ inputs: description: Enable verbose output. required: false default: 'false' + Version: + description: | + Specifies the version of the PSScriptAnalyzer module to install, using NuGet version-range syntax (for example '[1.0.0, 2.0.0)'). + When empty, the latest available version is installed. + required: false + Prerelease: + description: Allow prerelease versions of the PSScriptAnalyzer module if available. + required: false + default: 'false' PesterVersion: description: | Specifies the version of the Pester module to install, using NuGet version-range syntax (for example '[6.0.0,7.0.0)'). @@ -277,6 +286,8 @@ runs: id: test env: SettingsFilePath: ${{ fromJson(steps.paths.outputs.result).SettingsFilePath }} + PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_Version: ${{ inputs.Version }} + PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_Prerelease: ${{ inputs.Prerelease }} with: Debug: ${{ inputs.Debug }} GitHubPrerelease: ${{ inputs.GitHubPrerelease }} @@ -286,6 +297,7 @@ runs: Version: ${{ inputs.PesterVersion }} WorkingDirectory: ${{ inputs.WorkingDirectory }} TestResult_TestSuiteName: ${{ inputs.TestResult_TestSuiteName }} + Prescript: ${{ github.action_path }}/src/Install-PSScriptAnalyzer.ps1 Path: ${{ github.action_path }}/src/tests/PSScriptAnalyzer Run_Path: ${{ fromJson(steps.paths.outputs.result).CodePath }} ReportAsJson: ${{ inputs.ReportAsJson }} diff --git a/src/Install-PSScriptAnalyzer.ps1 b/src/Install-PSScriptAnalyzer.ps1 new file mode 100644 index 0000000..62b5afd --- /dev/null +++ b/src/Install-PSScriptAnalyzer.ps1 @@ -0,0 +1,75 @@ +<# + .SYNOPSIS + Ensures the requested PSScriptAnalyzer version is the only one installed and loaded. + + .DESCRIPTION + Runs as the Invoke-Pester prescript, in the same process as the analyzer test run. It installs the + PSScriptAnalyzer version selected through the action's Version/Prerelease inputs (retrying transient + PSGallery failures), removes any other PSScriptAnalyzer version from the session, and imports the chosen + version into the global session state. This guarantees the tests use the selected version instead of + PowerShell auto-loading whatever copy happens to be preinstalled on the runner. +#> + +[CmdletBinding()] +param() + +$moduleName = 'PSScriptAnalyzer' +$version = $env:PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_Version +$prerelease = $env:PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_Prerelease -eq 'true' + +$installParams = @{ + Name = $moduleName + Repository = 'PSGallery' + TrustRepository = $true + PassThru = $true + WarningAction = 'SilentlyContinue' +} +if (-not [string]::IsNullOrWhiteSpace($version)) { + $installParams['Version'] = $version +} +if ($prerelease) { + $installParams['Prerelease'] = $true +} + +$label = [string]::IsNullOrWhiteSpace($version) ? $moduleName : "$moduleName $version" +Write-Host "Installing module: $label" + +$installed = $null +$retryCount = 5 +$retryDelay = 10 +for ($i = 0; $i -lt $retryCount; $i++) { + try { + $installed = Install-PSResource @installParams + break + } catch { + Write-Warning "Installation of $moduleName failed with error: $_" + if ($i -eq $retryCount - 1) { + throw + } + Write-Warning "Retrying in $retryDelay seconds..." + Start-Sleep -Seconds $retryDelay + } +} + +# Resolve the exact version to load. Prefer what was just installed; if the resource was already +# present, Install-PSResource returns nothing, so fall back to the newest installed version that +# satisfies the requested constraint. +$resolved = $installed | Where-Object { $_.Name -eq $moduleName } | Sort-Object Version -Descending | Select-Object -First 1 +if (-not $resolved) { + $getParams = @{ Name = $moduleName; Verbose = $false; ErrorAction = 'SilentlyContinue' } + if (-not [string]::IsNullOrWhiteSpace($version)) { + $getParams['Version'] = $version + } + $resolved = Get-InstalledPSResource @getParams | Sort-Object Version -Descending | Select-Object -First 1 +} +if (-not $resolved) { + throw "No installed '$moduleName' version satisfies constraint '$version'." +} + +# Remove any already-loaded versions so only the chosen one remains, then import that exact version +# into the global session state used by the Pester run. +Write-Host "Removing any loaded '$moduleName' module from the session" +Remove-Module -Name $moduleName -Force -ErrorAction SilentlyContinue + +Write-Host "Importing module: $moduleName $($resolved.Version)" +Import-Module -Name $moduleName -RequiredVersion $resolved.Version -Force -Global