Skip to content

Commit 4d633e4

Browse files
🌟 [Major]: Control PSScriptAnalyzer, Pester, and GitHub module versions (#32)
Bumps `PSModule/Invoke-Pester` from 4.2.4 to 5.1.0 and reworks the action's version inputs so callers can independently pin the three modules the action relies on — and guarantees the pinned versions are the ones actually installed and loaded. Each module now follows the same convention used by its dedicated action, where the bare `Version`/`Prerelease` controls the namesake module: | Input | Controls | |---|---| | `Version` / `Prerelease` | PSScriptAnalyzer (this action's namesake module) | | `PesterVersion` / `PesterPrerelease` | Pester | | `GitHubVersion` / `GitHubPrerelease` | GitHub module | ## New: `Version` / `Prerelease` pin PSScriptAnalyzer The action now provisions the PSScriptAnalyzer module itself instead of relying on whatever copy is preinstalled on the runner. It installs the requested version (NuGet version-range syntax, for example `[1.0.0, 2.0.0)`; empty installs the latest), removes any other PSScriptAnalyzer version from the session, and imports the chosen version — so the analysis runs against exactly the version you selected. ## New: `PesterVersion` / `PesterPrerelease` and `GitHubVersion` / `GitHubPrerelease` Control the Pester module (the test runner) and the GitHub module (used to resolve paths and emit results) independently, both using NuGet version-range syntax. ## Breaking Changes `Version` and `Prerelease` changed meaning: they previously controlled the **GitHub** module; they now control **PSScriptAnalyzer**. Callers that pinned the GitHub module must switch to `GitHubVersion` / `GitHubPrerelease`. Before: ```yaml - uses: PSModule/Invoke-ScriptAnalyzer@v1 with: Version: '[1.2.0, 2.0.0)' # was the GitHub module Prerelease: 'true' ``` After: ```yaml - uses: PSModule/Invoke-ScriptAnalyzer@v2 with: Version: '[1.0.0, 2.0.0)' # PSScriptAnalyzer GitHubVersion: '[1.2.0, 2.0.0)' # GitHub module PesterVersion: '[6.0.0, 7.0.0)' # Pester ``` ## Technical Details - `action.yml`: `Version`/`Prerelease` (PSScriptAnalyzer) added; `PesterVersion`/`PesterPrerelease` and `GitHubVersion`/`GitHubPrerelease` retained. - `src/Install-PSScriptAnalyzer.ps1` (new): installs the requested PSScriptAnalyzer version (with PSGallery retry), `Remove-Module`s any loaded copy, then `Import-Module -RequiredVersion … -Global` for the resolved version. Wired via the Invoke-Pester step's `Prescript` input, so it runs in the same process as the analyzer run (`Version`/`Prerelease` passed through as env). - `Invoke-Pester` step bumped to v5.1.0 (SHA `4ff33199141fdf22568990b6107fe3148ae93a1c`): its `Version`/`Prerelease` (Pester) ← `PesterVersion`/`PesterPrerelease`; its `GitHubVersion`/`GitHubPrerelease` ← `GitHubVersion`/`GitHubPrerelease`. - `Get-TestPaths` (`GitHub-Script`) step: `Version`/`Prerelease` ← `GitHubVersion`/`GitHubPrerelease`. - `README.md`: inputs table updated to document all six version inputs. --------- Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Marius Storhaug <marstor@hotmail.com>
1 parent f3cbd69 commit 4d633e4

3 files changed

Lines changed: 113 additions & 9 deletions

File tree

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@ customize rule selection, severity filtering, and custom rule inclusion.
2121
| `SettingsFilePath` | The path to the settings file. | false | `.github/linters/.powershell-psscriptanalyzer.psd1` |
2222
| `Debug` | Enable debug output. | false | `'false'` |
2323
| `Verbose` | Enable verbose output. | false | `'false'` |
24-
| `Version` | Specifies the exact version of the GitHub module to install. | false | |
25-
| `Prerelease` | Allow prerelease versions if available. | false | `'false'` |
24+
| `Version` | Specifies the version of the PSScriptAnalyzer module to install (NuGet range). | false | |
25+
| `Prerelease` | Allow prerelease versions of the PSScriptAnalyzer module if available. | false | `'false'` |
26+
| `PesterVersion` | Specifies the version of the Pester module to install (NuGet range). | false | |
27+
| `PesterPrerelease` | Allow prerelease versions of the Pester module if available. | false | `'false'` |
28+
| `GitHubVersion` | Specifies the version of the GitHub module to install (NuGet range). | false | |
29+
| `GitHubPrerelease` | Allow prerelease versions of the GitHub module if available. | false | `'false'` |
2630
| `WorkingDirectory` | The working directory where the script runs. | false | `'.'` |
2731
| `ReportAsJson` | Output generated reports in JSON format in addition to the configured format. | false | `'true'` |
2832
| `Notice_Mode` | Controls when to show notices for test completion. | false | `'Failed'` |

action.yml

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,30 @@ inputs:
2222
required: false
2323
default: 'false'
2424
Version:
25-
description: Specifies the version of the GitHub module to be installed. The value must be an exact version.
25+
description: |
26+
Specifies the version of the PSScriptAnalyzer module to install, using NuGet version-range syntax (for example '[1.0.0, 2.0.0)').
27+
When empty, the latest available version is installed.
2628
required: false
2729
Prerelease:
28-
description: Allow prerelease versions if available.
30+
description: Allow prerelease versions of the PSScriptAnalyzer module if available.
31+
required: false
32+
default: 'false'
33+
PesterVersion:
34+
description: |
35+
Specifies the version of the Pester module to install, using NuGet version-range syntax (for example '[6.0.0,7.0.0)').
36+
When empty, the latest available version is installed.
37+
required: false
38+
PesterPrerelease:
39+
description: Allow prerelease versions of the Pester module if available.
40+
required: false
41+
default: 'false'
42+
GitHubVersion:
43+
description: |
44+
Specifies the version of the GitHub module to install, using NuGet version-range syntax (for example '[1.2.0, 2.0.0)').
45+
When empty, the latest available version is installed.
46+
required: false
47+
GitHubPrerelease:
48+
description: Allow prerelease versions of the GitHub module if available.
2949
required: false
3050
default: 'false'
3151
WorkingDirectory:
@@ -255,24 +275,29 @@ runs:
255275
PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_SettingsFilePath: ${{ inputs.SettingsFilePath }}
256276
with:
257277
Debug: ${{ inputs.Debug }}
258-
Prerelease: ${{ inputs.Prerelease }}
278+
Prerelease: ${{ inputs.GitHubPrerelease }}
259279
Verbose: ${{ inputs.Verbose }}
260-
Version: ${{ inputs.Version }}
280+
Version: ${{ inputs.GitHubVersion }}
261281
WorkingDirectory: ${{ inputs.WorkingDirectory }}
262282
Script: ${{ github.action_path }}/src/main.ps1
263283

264284
- name: Invoke-Pester
265-
uses: PSModule/Invoke-Pester@abddf7bef0d0614d7ca322036af6a06ee0fb4d44 # v4.2.4
285+
uses: PSModule/Invoke-Pester@4ff33199141fdf22568990b6107fe3148ae93a1c # v5.1.0
266286
id: test
267287
env:
268288
SettingsFilePath: ${{ fromJson(steps.paths.outputs.result).SettingsFilePath }}
289+
PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_Version: ${{ inputs.Version }}
290+
PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_Prerelease: ${{ inputs.Prerelease }}
269291
with:
270292
Debug: ${{ inputs.Debug }}
271-
Prerelease: ${{ inputs.Prerelease }}
293+
GitHubPrerelease: ${{ inputs.GitHubPrerelease }}
294+
GitHubVersion: ${{ inputs.GitHubVersion }}
295+
Prerelease: ${{ inputs.PesterPrerelease }}
272296
Verbose: ${{ inputs.Verbose }}
273-
Version: ${{ inputs.Version }}
297+
Version: ${{ inputs.PesterVersion }}
274298
WorkingDirectory: ${{ inputs.WorkingDirectory }}
275299
TestResult_TestSuiteName: ${{ inputs.TestResult_TestSuiteName }}
300+
Prescript: ${{ github.action_path }}/src/Install-PSScriptAnalyzer.ps1
276301
Path: ${{ github.action_path }}/src/tests/PSScriptAnalyzer
277302
Run_Path: ${{ fromJson(steps.paths.outputs.result).CodePath }}
278303
ReportAsJson: ${{ inputs.ReportAsJson }}

src/Install-PSScriptAnalyzer.ps1

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<#
2+
.SYNOPSIS
3+
Ensures the requested PSScriptAnalyzer version is the only one installed and loaded.
4+
5+
.DESCRIPTION
6+
Runs as the Invoke-Pester prescript, in the same process as the analyzer test run. It installs the
7+
PSScriptAnalyzer version selected through the action's Version/Prerelease inputs (retrying transient
8+
PSGallery failures), removes any other PSScriptAnalyzer version from the session, and imports the chosen
9+
version into the global session state. This guarantees the tests use the selected version instead of
10+
PowerShell auto-loading whatever copy happens to be preinstalled on the runner.
11+
#>
12+
13+
[CmdletBinding()]
14+
param()
15+
16+
$moduleName = 'PSScriptAnalyzer'
17+
$version = $env:PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_Version
18+
$prerelease = $env:PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_Prerelease -eq 'true'
19+
20+
$installParams = @{
21+
Name = $moduleName
22+
Repository = 'PSGallery'
23+
TrustRepository = $true
24+
PassThru = $true
25+
WarningAction = 'SilentlyContinue'
26+
}
27+
if (-not [string]::IsNullOrWhiteSpace($version)) {
28+
$installParams['Version'] = $version
29+
}
30+
if ($prerelease) {
31+
$installParams['Prerelease'] = $true
32+
}
33+
34+
$label = [string]::IsNullOrWhiteSpace($version) ? $moduleName : "$moduleName $version"
35+
Write-Host "Installing module: $label"
36+
37+
$installed = $null
38+
$retryCount = 5
39+
$retryDelay = 10
40+
for ($i = 0; $i -lt $retryCount; $i++) {
41+
try {
42+
$installed = Install-PSResource @installParams
43+
break
44+
} catch {
45+
Write-Warning "Installation of $moduleName failed with error: $_"
46+
if ($i -eq $retryCount - 1) {
47+
throw
48+
}
49+
Write-Warning "Retrying in $retryDelay seconds..."
50+
Start-Sleep -Seconds $retryDelay
51+
}
52+
}
53+
54+
# Resolve the exact version to load. Prefer what was just installed; if the resource was already
55+
# present, Install-PSResource returns nothing, so fall back to the newest installed version that
56+
# satisfies the requested constraint.
57+
$resolved = $installed | Where-Object { $_.Name -eq $moduleName } | Sort-Object Version -Descending | Select-Object -First 1
58+
if (-not $resolved) {
59+
$getParams = @{ Name = $moduleName; Verbose = $false; ErrorAction = 'SilentlyContinue' }
60+
if (-not [string]::IsNullOrWhiteSpace($version)) {
61+
$getParams['Version'] = $version
62+
}
63+
$resolved = Get-InstalledPSResource @getParams | Sort-Object Version -Descending | Select-Object -First 1
64+
}
65+
if (-not $resolved) {
66+
throw "No installed '$moduleName' version satisfies constraint '$version'."
67+
}
68+
69+
# Remove any already-loaded versions so only the chosen one remains, then import that exact version
70+
# into the global session state used by the Pester run.
71+
Write-Host "Removing any loaded '$moduleName' module from the session"
72+
Remove-Module -Name $moduleName -Force -ErrorAction SilentlyContinue
73+
74+
Write-Host "Importing module: $moduleName $($resolved.Version)"
75+
Import-Module -Name $moduleName -RequiredVersion $resolved.Version -Force -Global

0 commit comments

Comments
 (0)