-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInvoke-Tests.ps1
More file actions
92 lines (78 loc) · 3.53 KB
/
Copy pathInvoke-Tests.ps1
File metadata and controls
92 lines (78 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#Requires -Version 7.2
<#
.SYNOPSIS
Runs static analysis and the Pester test suite for LibreDevOpsHelpers.
.DESCRIPTION
Installs PSScriptAnalyzer and Pester if they are missing, runs PSScriptAnalyzer
against the module source using PSScriptAnalyzerSettings.psd1, then runs every
test under ./tests. Intended for local use and CI.
.PARAMETER SkipAnalyzer
Skip the PSScriptAnalyzer pass and run only Pester.
.EXAMPLE
./Invoke-Tests.ps1
#>
[CmdletBinding()]
param(
[switch]$SkipAnalyzer
)
$ErrorActionPreference = 'Stop'
$root = $PSScriptRoot
function Install-IfMissing {
param([string]$Name, [version]$MinimumVersion)
$existing = Get-Module -ListAvailable -Name $Name |
Where-Object { $_.Version -ge $MinimumVersion } |
Select-Object -First 1
if (-not $existing) {
Write-Host "Installing $Name ($MinimumVersion or newer)..."
Install-Module -Name $Name -MinimumVersion $MinimumVersion -Force -Scope CurrentUser -Repository PSGallery
}
}
if (-not $SkipAnalyzer) {
Install-IfMissing -Name 'PSScriptAnalyzer' -MinimumVersion '1.21.0'
Import-Module PSScriptAnalyzer
Write-Host 'Running PSScriptAnalyzer...'
$settings = Join-Path $root 'PSScriptAnalyzerSettings.psd1'
# Analyze each module file in its own invocation. A single recursive call can make
# PSScriptAnalyzer build more than one dynamic module in a single dynamic assembly,
# which throws on some runtimes; per-file invocation avoids that.
$moduleFiles = Get-ChildItem -Path (Join-Path $root 'LibreDevOpsHelpers') -Recurse -Filter '*.psm1'
# PSScriptAnalyzer has a long-standing intermittent engine bug that surfaces as a
# NullReferenceException ("Object reference not set to an instance of an object")
# from Invoke-ScriptAnalyzer. It is non-deterministic (the same file/commit passes
# on a re-run) and reproduces even with only the default rule set, so it is not our
# settings. Normally it is a non-terminating error, but $ErrorActionPreference='Stop'
# promotes it to a job failure. Retry the affected file a few times before giving up.
$maxAttempts = 3
$results = foreach ($file in $moduleFiles) {
for ($attempt = 1; $attempt -le $maxAttempts; $attempt++) {
try {
Invoke-ScriptAnalyzer -Path $file.FullName -Settings $settings -ErrorAction Stop
break
} catch [System.NullReferenceException] {
if ($attempt -eq $maxAttempts) {
throw "PSScriptAnalyzer threw NullReferenceException on '$($file.Name)' after $maxAttempts attempts: $($_.Exception.Message)"
}
Write-Warning "PSScriptAnalyzer NullReferenceException on '$($file.Name)' (attempt $attempt/$maxAttempts); retrying..."
Start-Sleep -Milliseconds 250
}
}
}
if ($results) {
$results | Format-Table -AutoSize | Out-String | Write-Host
$errors = @($results | Where-Object { $_.Severity -eq 'Error' })
if ($errors.Count -gt 0) {
throw "PSScriptAnalyzer found $($errors.Count) error(s)."
}
Write-Warning "PSScriptAnalyzer found $($results.Count) non-error finding(s)."
} else {
Write-Host 'PSScriptAnalyzer: clean.'
}
}
Install-IfMissing -Name 'Pester' -MinimumVersion '5.5.0'
Import-Module Pester
$config = New-PesterConfiguration
$config.Run.Path = Join-Path $root 'tests'
$config.Output.Verbosity = 'Detailed'
$config.Run.Exit = $true
Write-Host 'Running Pester...'
Invoke-Pester -Configuration $config