6363 SUMMARY_TOP : " 25"
6464 TOP_RULES : " 20"
6565
66- # SARIF run identity (stable across runs)
67- SARIF_RUN_ID : " powershell/psscriptanalyzer"
68-
6966 steps :
7067 - name : 📦 Checkout
7168 uses : actions/checkout@v4
@@ -144,7 +141,7 @@ jobs:
144141 echo "ref=${GITHUB_REF}" >> "$GITHUB_OUTPUT"
145142 echo "repo=${GITHUB_REPOSITORY}" >> "$GITHUB_OUTPUT"
146143
147- - name : ✅ Ensure report folder + baseline SARIF exist
144+ - name : ✅ Ensure report folder + baseline SARIF exist (VALID)
148145 if : steps.discover.outputs.count != '0'
149146 shell : pwsh
150147 run : |
@@ -155,13 +152,13 @@ jobs:
155152
156153 New-Item -ItemType Directory -Force -Path $outDir | Out-Null
157154
155+ # IMPORTANT: Do NOT add runAutomationDetails (rejected by upload-sarif validator in some environments)
158156 $baseline = @{
159157 '$schema' = 'http://json.schemastore.org/sarif-2.1.0'
160158 version = '2.1.0'
161159 runs = @(
162160 @{
163- tool = @{ driver = @{ name = 'PSScriptAnalyzer'; version = '0' } }
164- runAutomationDetails = @{ id = '${{ env.SARIF_RUN_ID }}' }
161+ tool = @{ driver = @{ name = 'PSScriptAnalyzer'; version = '0' } }
165162 results = @()
166163 }
167164 )
@@ -186,12 +183,12 @@ jobs:
186183
187184 $prune = [regex]::new('${{ env.PRUNE_DIR_REGEX }}')
188185
189- $repo = '${{ steps.meta.outputs.repo }}'
190- $sha = '${{ steps.meta.outputs.sha }}'
191- $ts = '${{ steps.meta.outputs.timestamp }}'
186+ $repo = '${{ steps.meta.outputs.repo }}'
187+ $sha = '${{ steps.meta.outputs.sha }}'
188+ $ts = '${{ steps.meta.outputs.timestamp }}'
192189 $runId = '${{ github.run_id }}'
193190
194- # Resolve folder roots (string paths only; do NOT pass string[] to -Path)
191+ # Resolve folder roots
195192 $roots = @("${{ env.ANALYZE_ROOTS }}".Split(" ", [System.StringSplitOptions]::RemoveEmptyEntries)) |
196193 ForEach-Object { Join-Path $root $_ } |
197194 Where-Object { Test-Path $_ -and -not $prune.IsMatch($_) }
@@ -203,18 +200,15 @@ jobs:
203200 $psaVersion = (Get-Module -ListAvailable PSScriptAnalyzer | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString()
204201
205202 $all = New-Object System.Collections.Generic.List[object]
206-
207203 foreach ($r in $roots) {
208204 $rRel = $r.Replace("$root$([IO.Path]::DirectorySeparatorChar)", '')
209205 Write-Host "Analyzing root: $rRel"
210206
211207 $res = Invoke-ScriptAnalyzer -Path $r -Recurse -Settings $settings -Severity @('Error','Warning','Information')
212- if ($res) {
213- foreach ($x in $res) { $all.Add($x) }
214- }
208+ if ($res) { foreach ($x in $res) { $all.Add($x) } }
215209 }
216210
217- # Normalize to report rows
211+ # Normalize
218212 $rows = New-Object System.Collections.Generic.List[object]
219213 foreach ($x in $all) {
220214 $rel = $x.ScriptPath.Replace("$root$([IO.Path]::DirectorySeparatorChar)", '').Replace('\','/')
@@ -231,11 +225,11 @@ jobs:
231225 })
232226 }
233227
234- # Always write JSON/CSV even if empty
228+ # Always write JSON/CSV
235229 $rows | ConvertTo-Json -Depth 8 | Set-Content -Path $jsonPath -Encoding UTF8
236230 $rows | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8
237231
238- # Build SARIF
232+ # SARIF (VALID — no runAutomationDetails)
239233 $sarifResults = New-Object System.Collections.Generic.List[object]
240234 foreach ($r in $rows) {
241235 $sarifLevel = switch ($r.Severity.ToLowerInvariant()) {
@@ -268,7 +262,20 @@ jobs:
268262 runs = @(
269263 @{
270264 tool = @{ driver = @{ name = 'PSScriptAnalyzer'; version = $psaVersion } }
271- runAutomationDetails = @{ id = '${{ env.SARIF_RUN_ID }}' }
265+
266+ # Accepted, helpful metadata (safe across validators)
267+ invocations = @(
268+ @{
269+ executionSuccessful = $true
270+ properties = @{
271+ repository = $repo
272+ commit = $sha
273+ run_id = $runId
274+ timestamp = $ts
275+ }
276+ }
277+ )
278+
272279 results = $sarifResults
273280 }
274281 )
@@ -277,11 +284,11 @@ jobs:
277284 $sarif | ConvertTo-Json -Depth 12 | Set-Content -Path $sarifPath -Encoding UTF8
278285
279286 # Markdown report
280- $total = $rows.Count
287+ $total = $rows.Count
281288 $bySev = $rows | Group-Object Severity | Sort-Object Name
282289 $byRule = $rows | Group-Object RuleName | Sort-Object Count -Descending
283290
284- $topN = [int]'${{ env.SUMMARY_TOP }}'
291+ $topN = [int]'${{ env.SUMMARY_TOP }}'
285292 $topRules = [int]'${{ env.TOP_RULES }}'
286293
287294 $md = New-Object System.Collections.Generic.List[string]
@@ -322,7 +329,7 @@ jobs:
322329 $mdText = [string]::Join([Environment]::NewLine, $md)
323330 $mdText | Set-Content -Path $mdPath -Encoding UTF8
324331
325- # Job Summary (short) — avoid `-join "`n"` parser issues
332+ # Job summary (short)
326333 $summary = New-Object System.Collections.Generic.List[string]
327334 $summary.Add("### 🧪 PowerShell Lint Summary")
328335 $summary.Add("- 🕒 **UTC:** $ts")
@@ -336,7 +343,7 @@ jobs:
336343 $summaryText = [string]::Join([Environment]::NewLine, $summary)
337344 $summaryText | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8
338345
339- # Gate: fail if any configured severities exist
346+ # Gate
340347 $failSev = @("${{ env.FAIL_ON_SEVERITIES }}".Split(" ", [System.StringSplitOptions]::RemoveEmptyEntries))
341348 if ($failSev.Count -gt 0) {
342349 $failHits = $rows | Where-Object { $_.Severity -in $failSev }
0 commit comments