Add formatting around warning for low scorecard levels

This commit is contained in:
Justin Hutchings
2024-03-04 19:34:29 +00:00
parent 1251834b92
commit f8ebb4b946
10 changed files with 52 additions and 32 deletions
+2 -1
View File
@@ -29,7 +29,8 @@ const defaultConfig: ConfigurationOptions = {
comment_summary_in_pr: true, comment_summary_in_pr: true,
retry_on_snapshot_warnings: false, retry_on_snapshot_warnings: false,
retry_on_snapshot_warnings_timeout: 120, retry_on_snapshot_warnings_timeout: 120,
warn_only: false warn_only: false,
warn_on_openssf_scorecard_level: 3
} }
const changesWithEmptyManifests: Changes = [ const changesWithEmptyManifests: Changes = [
+2 -2
View File
@@ -69,10 +69,10 @@ inputs:
description: Show a summary of the OpenSSF Scorecard scores. description: Show a summary of the OpenSSF Scorecard scores.
required: false required: false
default: true default: true
warn-on-openssf-scorecard-threshold: warn-on-openssf-scorecard-level:
description: Numeric threshold for the OpenSSF Scorecard score. If the score is below this threshold, the action will warn you. description: Numeric threshold for the OpenSSF Scorecard score. If the score is below this threshold, the action will warn you.
required: false required: false
default: 0 default: 3
outputs: outputs:
comment-content: comment-content:
description: Prepared dependency report comment description: Prepared dependency report comment
Generated Vendored
+18 -7
View File
@@ -887,6 +887,7 @@ exports.ConfigurationOptionsSchema = z
retry_on_snapshot_warnings: z.boolean().default(false), retry_on_snapshot_warnings: z.boolean().default(false),
retry_on_snapshot_warnings_timeout: z.number().default(120), retry_on_snapshot_warnings_timeout: z.number().default(120),
show_openssf_scorecard: z.boolean().optional(), show_openssf_scorecard: z.boolean().optional(),
warn_on_openssf_scorecard_level: z.number(),
comment_summary_in_pr: z comment_summary_in_pr: z
.union([ .union([
z.preprocess(val => (val === 'true' ? true : val === 'false' ? false : val), z.boolean()), z.preprocess(val => (val === 'true' ? true : val === 'false' ? false : val), z.boolean()),
@@ -962,7 +963,7 @@ exports.DepsDevProjectSchema = z
shortDescription: z.string(), shortDescription: z.string(),
url: z.string() url: z.string()
}), }),
score: z.string(), score: z.number(),
reason: z.string(), reason: z.string(),
details: z.array(z.string()) details: z.array(z.string())
})) }))
@@ -1322,18 +1323,25 @@ function snapshotWarningRecommendation(config, warnings) {
return 'Re-running this action after a short time may resolve the issue.'; return 'Re-running this action after a short time may resolve the issue.';
} }
function addScorecardToSummary(scorecard, config) { function addScorecardToSummary(scorecard, config) {
var _a, _b; var _a, _b, _c, _d;
core.summary.addHeading('OpenSSF Scorecard', 2); core.summary.addHeading('OpenSSF Scorecard', 2);
core.summary.addRaw(`<table><tr><th>Package</th><th>Version</th><th>Score</th><th>Details</th></tr>`, true); core.summary.addRaw(`<table><tr><th>Package</th><th>Version</th><th>Score</th><th>Details</th></tr>`, true);
for (const dependency of scorecard.dependencies) { for (const dependency of scorecard.dependencies) {
core.summary.addRaw(`<tr><td>${dependency.ecosystem}/${dependency.packageName}</td><td>${dependency.version}</td><td>${(_a = dependency.depsDevData) === null || _a === void 0 ? void 0 : _a.scorecard.overallScore}</td>`, false); core.summary.addRaw(`<tr><td>${dependency.ecosystem}/${dependency.packageName}</td><td>${dependency.version}</td>
<td>${((_a = dependency.depsDevData) === null || _a === void 0 ? void 0 : _a.scorecard.overallScore) == undefined ? 'Unknown' : (_b = dependency.depsDevData) === null || _b === void 0 ? void 0 : _b.scorecard.overallScore}</td>`, false);
if (((_c = dependency.depsDevData) === null || _c === void 0 ? void 0 : _c.scorecard.checks) !== undefined) {
let detailsTable = '<table><tr><th>Check</th><th>Score</th><th>Reason</th></tr>'; let detailsTable = '<table><tr><th>Check</th><th>Score</th><th>Reason</th></tr>';
for (const check of ((_b = dependency.depsDevData) === null || _b === void 0 ? void 0 : _b.scorecard.checks) || []) { for (const check of ((_d = dependency.depsDevData) === null || _d === void 0 ? void 0 : _d.scorecard.checks) || []) {
detailsTable += `<tr><td>${check.name}</td><td>${check.score}</td><td>${check.reason}</td></tr>`; let icon = (check.score < config.warn_on_openssf_scorecard_level) ? ":warning:" : ":green_circle:";
detailsTable += `<tr><td>${check.name}</td><td>${check.score}</td><td>${icon} ${check.reason}</td></tr>`;
} }
detailsTable += `</table>`; detailsTable += `</table>`;
core.summary.addRaw(`<td><details><summary>Details</summary>${detailsTable}</details></td></tr>`, true); core.summary.addRaw(`<td><details><summary>Details</summary>${detailsTable}</details></td></tr>`, true);
} }
else {
core.summary.addRaw('<td>Unknown</td></tr>', true);
}
}
core.summary.addRaw(`</table>`); core.summary.addRaw(`</table>`);
} }
exports.addScorecardToSummary = addScorecardToSummary; exports.addScorecardToSummary = addScorecardToSummary;
@@ -49701,6 +49709,7 @@ function readInlineConfig() {
const retry_on_snapshot_warnings_timeout = getOptionalNumber('retry-on-snapshot-warnings-timeout'); const retry_on_snapshot_warnings_timeout = getOptionalNumber('retry-on-snapshot-warnings-timeout');
const warn_only = getOptionalBoolean('warn-only'); const warn_only = getOptionalBoolean('warn-only');
const show_openssf_scorecard = getOptionalBoolean('show-openssf-scorecard'); const show_openssf_scorecard = getOptionalBoolean('show-openssf-scorecard');
const warn_on_openssf_scorecard_level = getOptionalNumber('warn-on-openssf-scorecard-level');
validatePURL(allow_dependencies_licenses); validatePURL(allow_dependencies_licenses);
validateLicenses('allow-licenses', allow_licenses); validateLicenses('allow-licenses', allow_licenses);
validateLicenses('deny-licenses', deny_licenses); validateLicenses('deny-licenses', deny_licenses);
@@ -49721,7 +49730,8 @@ function readInlineConfig() {
retry_on_snapshot_warnings, retry_on_snapshot_warnings,
retry_on_snapshot_warnings_timeout, retry_on_snapshot_warnings_timeout,
warn_only, warn_only,
show_openssf_scorecard show_openssf_scorecard,
warn_on_openssf_scorecard_level
}; };
return Object.fromEntries(Object.entries(keys).filter(([_, value]) => value !== undefined)); return Object.fromEntries(Object.entries(keys).filter(([_, value]) => value !== undefined));
} }
@@ -50020,6 +50030,7 @@ exports.ConfigurationOptionsSchema = z
retry_on_snapshot_warnings: z.boolean().default(false), retry_on_snapshot_warnings: z.boolean().default(false),
retry_on_snapshot_warnings_timeout: z.number().default(120), retry_on_snapshot_warnings_timeout: z.number().default(120),
show_openssf_scorecard: z.boolean().optional(), show_openssf_scorecard: z.boolean().optional(),
warn_on_openssf_scorecard_level: z.number(),
comment_summary_in_pr: z comment_summary_in_pr: z
.union([ .union([
z.preprocess(val => (val === 'true' ? true : val === 'false' ? false : val), z.boolean()), z.preprocess(val => (val === 'true' ? true : val === 'false' ? false : val), z.boolean()),
@@ -50095,7 +50106,7 @@ exports.DepsDevProjectSchema = z
shortDescription: z.string(), shortDescription: z.string(),
url: z.string() url: z.string()
}), }),
score: z.string(), score: z.number(),
reason: z.string(), reason: z.string(),
details: z.array(z.string()) details: z.array(z.string())
})) }))
Generated Vendored
+1 -1
View File
File diff suppressed because one or more lines are too long
+2 -1
View File
@@ -33,7 +33,8 @@ const defaultConfig: ConfigurationOptions = {
comment_summary_in_pr: true, comment_summary_in_pr: true,
retry_on_snapshot_warnings: false, retry_on_snapshot_warnings: false,
retry_on_snapshot_warnings_timeout: 120, retry_on_snapshot_warnings_timeout: 120,
warn_only: false warn_only: false,
warn_on_openssf_scorecard_level: 0
} }
const tmpDir = path.resolve(__dirname, '../tmp') const tmpDir = path.resolve(__dirname, '../tmp')
+3 -1
View File
@@ -49,6 +49,7 @@ function readInlineConfig(): ConfigurationOptionsPartial {
) )
const warn_only = getOptionalBoolean('warn-only') const warn_only = getOptionalBoolean('warn-only')
const show_openssf_scorecard = getOptionalBoolean('show-openssf-scorecard') const show_openssf_scorecard = getOptionalBoolean('show-openssf-scorecard')
const warn_on_openssf_scorecard_level = getOptionalNumber('warn-on-openssf-scorecard-level')
validatePURL(allow_dependencies_licenses) validatePURL(allow_dependencies_licenses)
validateLicenses('allow-licenses', allow_licenses) validateLicenses('allow-licenses', allow_licenses)
@@ -71,7 +72,8 @@ function readInlineConfig(): ConfigurationOptionsPartial {
retry_on_snapshot_warnings, retry_on_snapshot_warnings,
retry_on_snapshot_warnings_timeout, retry_on_snapshot_warnings_timeout,
warn_only, warn_only,
show_openssf_scorecard show_openssf_scorecard,
warn_on_openssf_scorecard_level
} }
return Object.fromEntries( return Object.fromEntries(
+1 -2
View File
@@ -8,8 +8,7 @@ import {
Severity, Severity,
Changes, Changes,
ConfigurationOptions, ConfigurationOptions,
Scorecard, Scorecard
DepsDevProject
} from './schemas' } from './schemas'
import {readConfig} from '../src/config' import {readConfig} from '../src/config'
import { import {
+2 -1
View File
@@ -52,6 +52,7 @@ export const ConfigurationOptionsSchema = z
retry_on_snapshot_warnings: z.boolean().default(false), retry_on_snapshot_warnings: z.boolean().default(false),
retry_on_snapshot_warnings_timeout: z.number().default(120), retry_on_snapshot_warnings_timeout: z.number().default(120),
show_openssf_scorecard: z.boolean().optional(), show_openssf_scorecard: z.boolean().optional(),
warn_on_openssf_scorecard_level: z.number(),
comment_summary_in_pr: z comment_summary_in_pr: z
.union([ .union([
z.preprocess( z.preprocess(
@@ -134,7 +135,7 @@ export const DepsDevProjectSchema = z
shortDescription: z.string(), shortDescription: z.string(),
url: z.string() url: z.string()
}), }),
score: z.string(), score: z.number(),
reason: z.string(), reason: z.string(),
details: z.array(z.string()) details: z.array(z.string())
}) })
+1 -3
View File
@@ -1,10 +1,8 @@
import { import {
Change, Change,
Changes,
DepsDevProject, DepsDevProject,
DepsDevProjectSchema, DepsDevProjectSchema,
Scorecard, Scorecard
ScorecardSchema
} from './schemas' } from './schemas'
import {isSPDXValid, octokitClient} from './utils' import {isSPDXValid, octokitClient} from './utils'
import {PackageURL} from 'packageurl-js' import {PackageURL} from 'packageurl-js'
+9 -2
View File
@@ -260,19 +260,26 @@ export function addScorecardToSummary(
) )
for (const dependency of scorecard.dependencies) { for (const dependency of scorecard.dependencies) {
core.summary.addRaw( core.summary.addRaw(
`<tr><td>${dependency.ecosystem}/${dependency.packageName}</td><td>${dependency.version}</td><td>${dependency.depsDevData?.scorecard.overallScore}</td>`, `<tr><td>${dependency.ecosystem}/${dependency.packageName}</td><td>${dependency.version}</td>
<td>${dependency.depsDevData?.scorecard.overallScore == undefined ? 'Unknown' : dependency.depsDevData?.scorecard.overallScore}</td>`,
false false
) )
if (dependency.depsDevData?.scorecard.checks !== undefined) {
let detailsTable = let detailsTable =
'<table><tr><th>Check</th><th>Score</th><th>Reason</th></tr>' '<table><tr><th>Check</th><th>Score</th><th>Reason</th></tr>'
for (const check of dependency.depsDevData?.scorecard.checks || []) { for (const check of dependency.depsDevData?.scorecard.checks || []) {
detailsTable += `<tr><td>${check.name}</td><td>${check.score}</td><td>${check.reason}</td></tr>` let icon = (check.score < config.warn_on_openssf_scorecard_level) ? ":warning:" : ":green_circle:"
detailsTable += `<tr><td>${check.name}</td><td>${check.score}</td><td>${icon} ${check.reason}</td></tr>`
} }
detailsTable += `</table>` detailsTable += `</table>`
core.summary.addRaw( core.summary.addRaw(
`<td><details><summary>Details</summary>${detailsTable}</details></td></tr>`, `<td><details><summary>Details</summary>${detailsTable}</details></td></tr>`,
true true
) )
} else {
core.summary.addRaw('<td>Unknown</td></tr>', true)
}
} }
core.summary.addRaw(`</table>`) core.summary.addRaw(`</table>`)
} }