Add 'show-patched-versions' option to configuration and update summary handling

- Introduced 'show-patched-versions' input in action.yml to control visibility of patched versions in vulnerability summaries.
- Updated default configuration and related functions to handle the new option.
- Enhanced tests to verify behavior with and without the patched version column.
This commit is contained in:
Chad Bentz
2026-02-27 14:58:54 -05:00
parent e404798400
commit aa60746a92
11 changed files with 166 additions and 57 deletions

View File

@@ -52,6 +52,7 @@ function readInlineConfig(): ConfigurationOptionsPartial {
const warn_on_openssf_scorecard_level = getOptionalNumber(
'warn-on-openssf-scorecard-level'
)
const show_patched_versions = getOptionalBoolean('show-patched-versions')
validateLicenses('allow-licenses', allow_licenses)
validateLicenses('deny-licenses', deny_licenses)
@@ -74,7 +75,8 @@ function readInlineConfig(): ConfigurationOptionsPartial {
retry_on_snapshot_warnings_timeout,
warn_only,
show_openssf_scorecard,
warn_on_openssf_scorecard_level
warn_on_openssf_scorecard_level,
show_patched_versions
}
return Object.fromEntries(

View File

@@ -207,7 +207,8 @@ async function run(): Promise<void> {
core.setOutput('vulnerable-changes', JSON.stringify(vulnerableChanges))
await summary.addChangeVulnerabilitiesToSummary(
vulnerableChanges,
minSeverity
minSeverity,
config.show_patched_versions
)
issueFound ||= await printVulnerabilitiesBlock(
vulnerableChanges,

View File

@@ -115,6 +115,7 @@ export const ConfigurationOptionsSchema = z
retry_on_snapshot_warnings_timeout: z.number().default(120),
show_openssf_scorecard: z.boolean().optional().default(true),
warn_on_openssf_scorecard_level: z.number().default(3),
show_patched_versions: z.boolean().default(false),
comment_summary_in_pr: z
.union([
z.preprocess(

View File

@@ -6,7 +6,8 @@ import {
groupDependenciesByManifest,
getManifestsSet,
renderUrl,
octokitClient
octokitClient,
isEnterprise
} from './utils'
import * as semver from 'semver'
@@ -277,7 +278,8 @@ async function promisePool(
export async function addChangeVulnerabilitiesToSummary(
vulnerableChanges: Changes,
severity: string
severity: string,
showPatchedVersions: boolean = false
): Promise<void> {
if (vulnerableChanges.length === 0) {
return
@@ -287,9 +289,18 @@ export async function addChangeVulnerabilitiesToSummary(
// Build set of unique advisories to query
const advisorySet = new Set<string>()
for (const pkg of vulnerableChanges) {
for (const vuln of pkg.vulnerabilities) {
advisorySet.add(vuln.advisory_ghsa_id)
if (showPatchedVersions) {
if (isEnterprise()) {
core.warning(
'show-patched-versions is not supported on GitHub Enterprise Server. The Patched Version column will be omitted.'
)
showPatchedVersions = false
} else {
for (const pkg of vulnerableChanges) {
for (const vuln of pkg.vulnerabilities) {
advisorySet.add(vuln.advisory_ghsa_id)
}
}
}
}
@@ -434,33 +445,42 @@ export async function addChangeVulnerabilitiesToSummary(
}
if (!sameAsPrevious) {
rows.push([
const row: SummaryTableRow = [
renderUrl(change.source_repository_url, change.name),
change.version,
renderUrl(vuln.advisory_url, vuln.advisory_summary),
vuln.severity,
patchVer
])
vuln.severity
]
if (showPatchedVersions) {
row.push(patchVer)
}
rows.push(row)
} else {
rows.push([
const row: SummaryTableRow = [
{data: '', colspan: '2'},
renderUrl(vuln.advisory_url, vuln.advisory_summary),
vuln.severity,
patchVer
])
vuln.severity
]
if (showPatchedVersions) {
row.push(patchVer)
}
rows.push(row)
}
previous_package = change.name
previous_version = change.version
}
}
const headerRow: SummaryTableRow = [
{data: 'Name', header: true},
{data: 'Version', header: true},
{data: 'Vulnerability', header: true},
{data: 'Severity', header: true}
]
if (showPatchedVersions) {
headerRow.push({data: 'Patched Version', header: true})
}
core.summary.addHeading(`<em>${manifest}</em>`, 4).addTable([
[
{data: 'Name', header: true},
{data: 'Version', header: true},
{data: 'Vulnerability', header: true},
{data: 'Severity', header: true},
{data: 'Patched Version', header: true}
],
headerRow,
...rows
])
}

View File

@@ -33,7 +33,7 @@ export function renderUrl(url: string | null, text: string): string {
}
}
function isEnterprise(): boolean {
export function isEnterprise(): boolean {
const serverUrl = new URL(
process.env['GITHUB_SERVER_URL'] ?? 'https://github.com'
)