Skip to content

Commit 03fb8f8

Browse files
Update psscriptanalyzer-plus-sarif.yml
Signed-off-by: LUIZ HAMILTON ROBERTO DA SILVA <[email protected]>
1 parent a807808 commit 03fb8f8

1 file changed

Lines changed: 61 additions & 28 deletions

File tree

.github/workflows/psscriptanalyzer-plus-sarif.yml

Lines changed: 61 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,10 @@ jobs:
5656
ProSuite-Hub
5757
SysAdmin-Tools
5858
59-
# Severity gating policy:
60-
# - Workflow FAILS if any "Error" findings exist
59+
# Fail gate: job fails if ANY of these severities exist
6160
FAIL_ON_SEVERITIES: "Error"
6261

63-
# Optional: cap the amount of findings shown in summary
62+
# Optional: cap the amount of findings shown in summary/report
6463
SUMMARY_TOP: "25"
6564

6665
steps:
@@ -118,7 +117,6 @@ jobs:
118117
$settingsPath = Join-Path $env:GITHUB_WORKSPACE '${{ env.SETTINGS_FILE }}'
119118
if (-not (Test-Path $settingsPath)) { throw "Missing settings file: $settingsPath" }
120119
121-
# Must be a hashtable when imported
122120
$cfg = Import-PowerShellDataFile -Path $settingsPath
123121
if (-not ($cfg -is [hashtable])) { throw "Settings file is not a hashtable: $settingsPath" }
124122
@@ -142,6 +140,39 @@ jobs:
142140
echo "ref=${GITHUB_REF}" >> "$GITHUB_OUTPUT"
143141
echo "repo=${GITHUB_REPOSITORY}" >> "$GITHUB_OUTPUT"
144142
143+
- name: 🗂️ Ensure report folder exists
144+
if: steps.discover.outputs.count != '0'
145+
shell: pwsh
146+
run: |
147+
$ErrorActionPreference = 'Stop'
148+
$outDir = Join-Path $env:GITHUB_WORKSPACE '${{ env.OUT_DIR }}'
149+
New-Item -ItemType Directory -Force -Path $outDir | Out-Null
150+
Write-Host "Report folder ready: $outDir"
151+
152+
# OPTION A: Always create a baseline SARIF so Code Scanning never breaks due to missing file
153+
- name: ✅ Create baseline SARIF (always)
154+
if: steps.discover.outputs.count != '0'
155+
shell: pwsh
156+
run: |
157+
$ErrorActionPreference = 'Stop'
158+
$root = $env:GITHUB_WORKSPACE
159+
$outDir = Join-Path $root '${{ env.OUT_DIR }}'
160+
$sarif = Join-Path $outDir '${{ env.OUT_SARIF }}'
161+
New-Item -ItemType Directory -Force -Path $outDir | Out-Null
162+
163+
$baseline = @{
164+
'$schema' = 'http://json.schemastore.org/sarif-2.1.0'
165+
version = '2.1.0'
166+
runs = @(
167+
@{
168+
tool = @{ driver = @{ name = 'PSScriptAnalyzer'; version = '${{ env.PSA_VERSION }}' } }
169+
results = @()
170+
}
171+
)
172+
}
173+
$baseline | ConvertTo-Json -Depth 10 | Set-Content -Path $sarif -Encoding UTF8
174+
Write-Host "Baseline SARIF created: $sarif"
175+
145176
- name: 🔎 Run PSScriptAnalyzer + Build Reports (JSON/CSV/MD/SARIF)
146177
if: steps.discover.outputs.count != '0'
147178
shell: pwsh
@@ -160,7 +191,6 @@ jobs:
160191
161192
$prune = [regex]::new('${{ env.PRUNE_DIR_REGEX }}')
162193
163-
# Resolve folder roots (string paths only)
164194
$roots = @("${{ env.ANALYZE_ROOTS }}".Split(" ", [System.StringSplitOptions]::RemoveEmptyEntries)) |
165195
ForEach-Object { Join-Path $root $_ } |
166196
Where-Object { Test-Path $_ -and -not $prune.IsMatch($_) }
@@ -182,33 +212,33 @@ jobs:
182212
foreach ($x in $results) {
183213
$rel = $x.ScriptPath.Replace("$root$([IO.Path]::DirectorySeparatorChar)", '').Replace('\','/')
184214
$rows += [pscustomobject]@{
185-
Severity = [string]$x.Severity
186-
RuleName = [string]$x.RuleName
187-
Message = [string]$x.Message
188-
File = $rel
189-
Line = [int]$x.Line
190-
Column = [int]$x.Column
191-
EndLine = [int]$x.EndLine
192-
EndColumn = [int]$x.EndColumn
193-
ScriptName = [string]$x.ScriptName
215+
Severity = [string]$x.Severity
216+
RuleName = [string]$x.RuleName
217+
Message = [string]$x.Message
218+
File = $rel
219+
Line = [int]$x.Line
220+
Column = [int]$x.Column
221+
EndLine = [int]$x.EndLine
222+
EndColumn = [int]$x.EndColumn
223+
ScriptName = [string]$x.ScriptName
194224
}
195225
}
196226
197-
# JSON (full)
227+
# JSON
198228
$rows | ConvertTo-Json -Depth 8 | Set-Content -Path $jsonPath -Encoding UTF8
199229
200-
# CSV (business-friendly)
230+
# CSV
201231
$rows | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8
202232
203-
# SARIF (simple + reliable)
233+
# SARIF (overwrite baseline with actual results)
204234
$psaVersion = (Get-Module -ListAvailable PSScriptAnalyzer | Sort-Object Version -Descending | Select-Object -First 1).Version.ToString()
205235
$sarifResults = @()
206236
207237
foreach ($r in $rows) {
208238
$sarifLevel = switch ($r.Severity.ToLowerInvariant()) {
209-
'error' { 'error' }
210-
'warning' { 'warning' }
211-
default { 'note' }
239+
'error' { 'error' }
240+
'warning' { 'warning' }
241+
default { 'note' }
212242
}
213243
214244
$sarifResults += @{
@@ -241,9 +271,9 @@ jobs:
241271
}
242272
$sarif | ConvertTo-Json -Depth 12 | Set-Content -Path $sarifPath -Encoding UTF8
243273
244-
# Markdown report (executive + technical)
245-
$total = $rows.Count
246-
$bySev = $rows | Group-Object Severity | Sort-Object Name
274+
# Markdown report
275+
$total = $rows.Count
276+
$bySev = $rows | Group-Object Severity | Sort-Object Name
247277
$byRule = $rows | Group-Object RuleName | Sort-Object Count -Descending
248278
249279
$repo = '${{ steps.meta.outputs.repo }}'
@@ -285,9 +315,10 @@ jobs:
285315
$md.Add("| $($i.Severity) | `$($i.RuleName)` | [$($i.File)]($fileLink) | $($i.Line) | $msg |")
286316
}
287317
288-
$md -join "`n" | Set-Content -Path $mdPath -Encoding UTF8
318+
$mdText = ($md -join "`n")
319+
$mdText | Set-Content -Path $mdPath -Encoding UTF8
289320
290-
# Job summary (short)
321+
# Job summary (short) - SAFE join
291322
$summary = New-Object System.Collections.Generic.List[string]
292323
$summary.Add("### 🧪 PowerShell Lint Summary")
293324
$summary.Add("- 🕒 **UTC:** $ts")
@@ -298,7 +329,8 @@ jobs:
298329
$summary.Add("")
299330
$summary.Add("Artifacts: JSON / CSV / MD / SARIF are in `${{ env.OUT_DIR }}`")
300331
301-
$summary -join "`n" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8
332+
$summaryText = ($summary -join "`n")
333+
$summaryText | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8
302334
303335
# Gate: fail if any configured severities exist
304336
$failSev = @("${{ env.FAIL_ON_SEVERITIES }}".Split(" ", [System.StringSplitOptions]::RemoveEmptyEntries))
@@ -310,15 +342,16 @@ jobs:
310342
}
311343
312344
- name: 📦 Upload Report Artifacts (Structured)
313-
if: always()
345+
if: always() && hashFiles(format('{0}/{1}/*', github.workspace, env.OUT_DIR)) != ''
314346
uses: actions/upload-artifact@v4
315347
with:
316348
name: powershell-lint-reports
317349
path: ${{ github.workspace }}/${{ env.OUT_DIR }}
318350
retention-days: 30
319351

352+
# OPTION B: Only upload SARIF if it exists
320353
- name: 🛰️ Upload SARIF to GitHub Code Scanning
321-
if: always()
354+
if: always() && hashFiles(format('{0}/{1}/{2}', github.workspace, env.OUT_DIR, env.OUT_SARIF)) != ''
322355
uses: github/codeql-action/upload-sarif@v4
323356
with:
324357
sarif_file: ${{ github.workspace }}/${{ env.OUT_DIR }}/${{ env.OUT_SARIF }}

0 commit comments

Comments
 (0)