microsoft/hve-core

Public

mirrored from https://github.com/microsoft/hve-coreAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
hve-core-v3.2.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

scripts/linting/Invoke-PSScriptAnalyzer.ps1

206lines · modeblame

66be1367Bill Berry7 months ago1#!/usr/bin/env pwsh
d19c9b3alittleKitchen5 months ago2# Copyright (c) Microsoft Corporation.
3# SPDX-License-Identifier: MIT
66be1367Bill Berry7 months ago4#
5# Invoke-PSScriptAnalyzer.ps1
6#
7# Purpose: Wrapper for PSScriptAnalyzer with GitHub Actions integration
8# Author: HVE Core Team
9
6e262826little Kitchen5 months ago10#Requires -Version 7.0
11
66be1367Bill Berry7 months ago12[CmdletBinding()]
13param(
14[Parameter(Mandatory = $false)]
15[switch]$ChangedFilesOnly,
16
17[Parameter(Mandatory = $false)]
18[string]$BaseBranch = "origin/main",
19
20[Parameter(Mandatory = $false)]
21[string]$ConfigPath = (Join-Path $PSScriptRoot "PSScriptAnalyzer.psd1"),
22
23[Parameter(Mandatory = $false)]
24[string]$OutputPath = "logs/psscriptanalyzer-results.json"
25)
26
6e262826little Kitchen5 months ago27$ErrorActionPreference = 'Stop'
28
66be1367Bill Berry7 months ago29# Import shared helpers
30Import-Module (Join-Path $PSScriptRoot "Modules/LintingHelpers.psm1") -Force
fdd75ed7Bill Berry5 months ago31Import-Module (Join-Path $PSScriptRoot "../lib/Modules/CIHelpers.psm1") -Force
66be1367Bill Berry7 months ago32
6b84a8e4Bill Berry4 months ago33#region Functions
66be1367Bill Berry7 months ago34
6b84a8e4Bill Berry4 months ago35function Invoke-PSScriptAnalyzerCore {
36[CmdletBinding()]
37[OutputType([void])]
38param(
39[Parameter(Mandatory = $false)]
40[switch]$ChangedFilesOnly,
66be1367Bill Berry7 months ago41
6b84a8e4Bill Berry4 months ago42[Parameter(Mandatory = $false)]
43[string]$BaseBranch = "origin/main",
66be1367Bill Berry7 months ago44
6b84a8e4Bill Berry4 months ago45[Parameter(Mandatory = $false)]
46[string]$ConfigPath = (Join-Path $PSScriptRoot "PSScriptAnalyzer.psd1"),
66be1367Bill Berry7 months ago47
6b84a8e4Bill Berry4 months ago48[Parameter(Mandatory = $false)]
49[string]$OutputPath = "logs/psscriptanalyzer-results.json"
50)
66be1367Bill Berry7 months ago51
6b84a8e4Bill Berry4 months ago52Write-Host "🔍 Running PSScriptAnalyzer..." -ForegroundColor Cyan
66be1367Bill Berry7 months ago53
6b84a8e4Bill Berry4 months ago54# Ensure PSScriptAnalyzer is available
55if (-not (Get-Module -ListAvailable -Name PSScriptAnalyzer)) {
56Write-Host "Installing PSScriptAnalyzer module..." -ForegroundColor Yellow
57Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser -Repository PSGallery
58}
59
60Import-Module PSScriptAnalyzer
61
62# Get files to analyze
63$filesToAnalyze = @()
64
65if ($ChangedFilesOnly) {
66Write-Host "Detecting changed PowerShell files..." -ForegroundColor Cyan
67$filesToAnalyze = @(Get-ChangedFilesFromGit -BaseBranch $BaseBranch -FileExtensions @('*.ps1', '*.psm1', '*.psd1'))
68}
69else {
70Write-Host "Analyzing all PowerShell files..." -ForegroundColor Cyan
f120b93bBill Berry4 months ago71$filesToAnalyze = @(Get-FilesRecursive -Path "." -Include @('*.ps1', '*.psm1', '*.psd1'))
6b84a8e4Bill Berry4 months ago72}
73
74if (@($filesToAnalyze).Count -eq 0) {
75Write-Host "✅ No PowerShell files to analyze" -ForegroundColor Green
76Set-CIOutput -Name "count" -Value "0"
77Set-CIOutput -Name "issues" -Value "0"
78return
79}
80
81Write-Host "Analyzing $($filesToAnalyze.Count) PowerShell files..." -ForegroundColor Cyan
82Set-CIOutput -Name "count" -Value $filesToAnalyze.Count
66be1367Bill Berry7 months ago83
35c44178o75 months ago84# Run PSScriptAnalyzer
85$allResults = @()
86$hasErrors = $false
87
88foreach ($file in $filesToAnalyze) {
89$filePath = if ($file -is [System.IO.FileInfo]) { $file.FullName } else { $file }
90Write-Host "`n📄 Analyzing: $filePath" -ForegroundColor Cyan
66be1367Bill Berry7 months ago91
35c44178o75 months ago92$results = Invoke-ScriptAnalyzer -Path $filePath -Settings $ConfigPath
93
94if ($results) {
95$allResults += $results
66be1367Bill Berry7 months ago96
35c44178o75 months ago97foreach ($result in $results) {
3587e6abBill Berry5 months ago98$annotationLevel = switch ($result.Severity) {
99'Error' { 'Error' }
100'Warning' { 'Warning' }
101'Information' { 'Notice' }
102default { 'Notice' }
103}
104
105Write-CIAnnotation `
35c44178o75 months ago106-Message "$($result.RuleName): $($result.Message)" `
3587e6abBill Berry5 months ago107-Level $annotationLevel `
35c44178o75 months ago108-File $filePath `
109-Line $result.Line `
110-Column $result.Column
111
112$icon = switch ($result.Severity) {
113'Error' { '❌'; $hasErrors = $true }
114'Warning' { '⚠️' }
115default { 'ℹ️' }
116}
117
118Write-Host " $icon [$($result.Severity)] $($result.RuleName): $($result.Message) (Line $($result.Line))" -ForegroundColor $(
119if ($result.Severity -eq 'Error') { 'Red' }
120elseif ($result.Severity -eq 'Warning') { 'Yellow' }
121else { 'Cyan' }
122)
66be1367Bill Berry7 months ago123}
35c44178o75 months ago124}
125else {
126Write-Host " ✅ No issues found" -ForegroundColor Green
66be1367Bill Berry7 months ago127}
128}
129
35c44178o75 months ago130# Export results
131$summary = @{
de43e73eKatrien De Graeve5 months ago132TotalFiles = @($filesToAnalyze).Count
133TotalIssues = @($allResults).Count
134Errors = @($allResults | Where-Object Severity -eq 'Error').Count
135Warnings = @($allResults | Where-Object Severity -eq 'Warning').Count
136Information = @($allResults | Where-Object Severity -eq 'Information').Count
35c44178o75 months ago137HasErrors = $hasErrors
138}
66be1367Bill Berry7 months ago139
67585f5aAndrew Vineyard4 months ago140# Ensure logs directory exists
141$logsDir = Split-Path $OutputPath -Parent
142if (-not (Test-Path $logsDir)) {
143New-Item -ItemType Directory -Force -Path $logsDir | Out-Null
144}
145
35c44178o75 months ago146$allResults | ConvertTo-Json -Depth 5 | Out-File $OutputPath
67585f5aAndrew Vineyard4 months ago147$summary | ConvertTo-Json | Out-File (Join-Path $logsDir "psscriptanalyzer-summary.json")
66be1367Bill Berry7 months ago148
35c44178o75 months ago149# Set outputs
3587e6abBill Berry5 months ago150Set-CIOutput -Name "issues" -Value $summary.TotalIssues
151Set-CIOutput -Name "errors" -Value $summary.Errors
152Set-CIOutput -Name "warnings" -Value $summary.Warnings
66be1367Bill Berry7 months ago153
35c44178o75 months ago154if ($hasErrors) {
3587e6abBill Berry5 months ago155Set-CIEnv -Name "PSSCRIPTANALYZER_FAILED" -Value "true"
35c44178o75 months ago156}
66be1367Bill Berry7 months ago157
35c44178o75 months ago158# Write summary
3587e6abBill Berry5 months ago159Write-CIStepSummary -Content "## PSScriptAnalyzer Results`n"
66be1367Bill Berry7 months ago160
35c44178o75 months ago161if ($summary.TotalIssues -eq 0) {
3587e6abBill Berry5 months ago162Write-CIStepSummary -Content "✅ **Status**: Passed`n`nAll $($summary.TotalFiles) PowerShell files passed linting checks."
35c44178o75 months ago163Write-Host "`n✅ All PowerShell files passed PSScriptAnalyzer checks!" -ForegroundColor Green
6b84a8e4Bill Berry4 months ago164return
35c44178o75 months ago165}
166else {
3587e6abBill Berry5 months ago167Write-CIStepSummary -Content @"
66be1367Bill Berry7 months ago168❌ **Status**: Failed
169
170| Metric | Count |
171|--------|-------|
172| Files Analyzed | $($summary.TotalFiles) |
173| Total Issues | $($summary.TotalIssues) |
174| Errors | $($summary.Errors) |
175| Warnings | $($summary.Warnings) |
176| Information | $($summary.Information) |
177"@
178
35c44178o75 months ago179Write-Host "`n❌ PSScriptAnalyzer found $($summary.TotalIssues) issue(s)" -ForegroundColor Red
6b84a8e4Bill Berry4 months ago180throw "PSScriptAnalyzer found $($summary.TotalIssues) issue(s)"
35c44178o75 months ago181}
182}
6b84a8e4Bill Berry4 months ago183
184#endregion Functions
185
186#region Main Execution
187
188if ($MyInvocation.InvocationName -ne '.') {
f120b93bBill Berry4 months ago189# Strip /mnt/* paths from PATH to avoid slow 9P cross-filesystem
190# lookups in WSL. PSScriptAnalyzer resolves commands by scanning every
191# PATH directory per file; Windows mount points add ~40s per file.
192$env:PATH = ($env:PATH -split [System.IO.Path]::PathSeparator |
193Where-Object { $_ -notlike '/mnt/*' }) -join [System.IO.Path]::PathSeparator
194
6b84a8e4Bill Berry4 months ago195try {
196Invoke-PSScriptAnalyzerCore -ChangedFilesOnly:$ChangedFilesOnly -BaseBranch $BaseBranch -ConfigPath $ConfigPath -OutputPath $OutputPath
197exit 0
198}
199catch {
200Write-Error -ErrorAction Continue "PSScriptAnalyzer failed: $($_.Exception.Message)"
201Write-CIAnnotation -Message $_.Exception.Message -Level Error
202exit 1
203}
66be1367Bill Berry7 months ago204}
6b84a8e4Bill Berry4 months ago205
206#endregion Main Execution