microsoft/hve-core

Public

mirrored fromhttps://github.com/microsoft/hve-coreAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
feat/1637-e-ps74-pytest

Branches

Tags

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

Clone

HTTPS

Download ZIP

.github/skills/github/gh-code-scanning/scripts/Get-CodeScanningAlerts.ps1

121lines · modecode

1#!/usr/bin/env pwsh
2# Copyright (c) Microsoft Corporation.
3# SPDX-License-Identifier: MIT
4#Requires -Version 7.0
5
6<#
7.SYNOPSIS
8 Retrieves open code scanning alerts from a GitHub repository, grouped by rule.
9
10.DESCRIPTION
11 Uses the gh CLI to fetch open code scanning alerts for a repository and branch,
12 suppressing the pager for non-interactive output. Results are grouped by rule
13 description and sorted by occurrence count descending.
14
15 Requires gh CLI authenticated with security_events scope (or public_repo for public repos).
16
17.PARAMETER Owner
18 GitHub organization or user name (e.g., 'microsoft').
19
20.PARAMETER Repo
21 Repository name without the owner (e.g., 'edge-ai').
22
23.PARAMETER Branch
24 Branch name to scope alerts to. Defaults to 'main'.
25
26.PARAMETER OutputFormat
27 Output format: Table (default), Json, or GroupedJson.
28 - Table: Human-readable summary table.
29 - Json: Full grouped alert objects as JSON array.
30 - GroupedJson: Alias for Json; produces the same output.
31
32.EXAMPLE
33 ./Get-CodeScanningAlerts.ps1 -Owner microsoft -Repo edge-ai
34
35.EXAMPLE
36 ./Get-CodeScanningAlerts.ps1 -Owner microsoft -Repo edge-ai -Branch develop -OutputFormat Json
37#>
38[CmdletBinding()]
39param(
40 [Parameter(Mandatory = $true)]
41 [ValidatePattern('^[a-zA-Z0-9._-]+$', ErrorMessage = 'Owner must contain only alphanumeric characters, dots, hyphens, or underscores.')]
42 [string]$Owner,
43
44 [Parameter(Mandatory = $true)]
45 [ValidatePattern('^[a-zA-Z0-9._-]+$', ErrorMessage = 'Repo must contain only alphanumeric characters, dots, hyphens, or underscores.')]
46 [string]$Repo,
47
48 [Parameter()]
49 [ValidatePattern('^[a-zA-Z0-9._/-]+$', ErrorMessage = 'Branch must contain only alphanumeric characters, dots, hyphens, underscores, or slashes.')]
50 [string]$Branch = 'main',
51
52 [Parameter()]
53 [ValidateSet('Table', 'Json', 'GroupedJson')]
54 [string]$OutputFormat = 'Table'
55)
56
57$ErrorActionPreference = 'Stop'
58
59#region Main Execution
60
61if ($MyInvocation.InvocationName -ne '.') {
62 $env:GH_PAGER = ''
63
64 if (-not (Get-Command gh -ErrorAction SilentlyContinue)) {
65 Write-Error "gh CLI not found. Install it from https://cli.github.com and re-run this script."
66 }
67
68 gh auth status 2>&1 | Out-Null
69 if ($LASTEXITCODE -ne 0) {
70 Write-Error "gh CLI is not authenticated. Run 'gh auth login' and ensure the 'security_events' scope is granted, then re-run this script."
71 }
72
73 $Url = "repos/$Owner/$Repo/code-scanning/alerts?state=open&ref=refs/heads/$Branch&per_page=100"
74 $Raw = gh api $Url --paginate --jq '.[]'
75
76 if ($LASTEXITCODE -ne 0) {
77 if ($Raw -match '403|Resource not accessible by integration') {
78 Write-Error "gh api call failed: missing required scope. Run 'gh auth refresh -s security_events' and re-run this script."
79 }
80 Write-Error "gh api call failed (exit $LASTEXITCODE): $Raw"
81 }
82
83 $Alerts = @($Raw | ConvertFrom-Json)
84
85 $Grouped = $Alerts |
86 Group-Object { $_.rule.description } |
87 ForEach-Object {
88 $paths = @(
89 $_.Group |
90 ForEach-Object { $_.most_recent_instance.location.path } |
91 Where-Object { $_ -and $_ -ne 'no file associated with this alert' } |
92 Sort-Object -Unique
93 )
94 [PSCustomObject]@{
95 RuleDescription = $_.Name
96 RuleId = $_.Group[0].rule.id
97 Tool = $_.Group[0].tool.name
98 SecuritySeverity = $_.Group[0].rule.security_severity_level
99 Severity = $_.Group[0].rule.severity
100 Count = $_.Count
101 AffectedPaths = $paths
102 HasFilePaths = ($paths.Count -gt 0)
103 AlertUrl = $_.Group[0].html_url
104 FindingDescription = $_.Group[0].most_recent_instance.message.text
105 }
106 } |
107 Sort-Object -Property Count -Descending
108
109 switch ($OutputFormat) {
110 'Table' {
111 $Grouped | Format-Table -AutoSize -Property Count, SecuritySeverity, RuleId, RuleDescription
112 }
113 { $_ -in 'Json', 'GroupedJson' } {
114 $Grouped | ConvertTo-Json -Depth 5
115 }
116 }
117
118 exit 0
119}
120
121#endregion Main Execution
122