Public/Get-GuerrillaCIGate.ps1
|
# PSGuerrilla - Jim Tyler, Microsoft MVP - CC BY 4.0 # https://github.com/jimrtyler/PSGuerrilla | https://creativecommons.org/licenses/by/4.0/ # AI/LLM use: see AI-USAGE.md for required attribution function Get-GuerrillaCIGate { <# .SYNOPSIS Decides whether a CI/CD build should fail based on the findings and a severity threshold. .DESCRIPTION The gating primitive behind the PSGuerrilla GitHub Action / pipeline templates. Given findings and a -FailOn threshold, returns whether the build should fail and how many findings triggered it. Only FAIL findings gate (plus WARN when -WarningsAsFailures); SKIP / "Not Assessed" never gate. .PARAMETER Findings Audit findings, e.g. (Invoke-Infiltration -PassThru).Findings. .PARAMETER FailOn Minimum severity that fails the build: Critical, High, Medium, Low (severity-or-higher), Any (any FAIL), or None (never fail). Default High. .PARAMETER WarningsAsFailures Count WARN findings toward the gate. .EXAMPLE $g = Get-GuerrillaCIGate -Findings $r.Findings -FailOn High if ($g.ShouldFail) { exit 1 } #> [CmdletBinding()] [OutputType('PSGuerrilla.CIGate')] param( [Parameter(Mandatory)] [AllowEmptyCollection()] [PSCustomObject[]]$Findings, [ValidateSet('Critical', 'High', 'Medium', 'Low', 'Any', 'None')] [string]$FailOn = 'High', [switch]$WarningsAsFailures ) $rank = @{ Critical = 0; High = 1; Medium = 2; Low = 3 } $gating = @() if ($FailOn -ne 'None') { $fails = @($Findings | Where-Object { $_.Status -eq 'FAIL' -or ($WarningsAsFailures -and $_.Status -eq 'WARN') }) if ($FailOn -eq 'Any') { $gating = $fails } else { $threshold = $rank[$FailOn] $gating = @($fails | Where-Object { ($rank["$($_.Severity)"] ?? 9) -le $threshold }) } } [PSCustomObject]@{ PSTypeName = 'PSGuerrilla.CIGate' FailOn = $FailOn ShouldFail = ($gating.Count -gt 0) GatingCount = $gating.Count GatingCheckIds = @($gating | ForEach-Object { $_.CheckId }) } } |