Fix broken tests, clean up dead code

This commit is contained in:
Justin Hutchings
2024-03-12 21:32:27 +00:00
parent 7dc5f537be
commit 72666694f0
8 changed files with 111 additions and 33 deletions

View File

@@ -1,4 +1,4 @@
import {expect, jest, test} from '@jest/globals'
import {expect, test} from '@jest/globals'
import {Change, Changes} from '../src/schemas'
import {getScorecardLevels, getProjectUrl} from '../src/scorecard'

View File

@@ -1,5 +1,5 @@
import {expect, jest, test} from '@jest/globals'
import {Changes, ConfigurationOptions} from '../src/schemas'
import {Changes, ConfigurationOptions, Scorecard} from '../src/schemas'
import * as summary from '../src/summary'
import * as core from '@actions/core'
import {createTestChange} from './fixtures/create-test-change'
@@ -16,6 +16,9 @@ const emptyInvalidLicenseChanges = {
unresolved: [],
unlicensed: []
}
const emptyScorecard: Scorecard = {
dependencies: []
}
const defaultConfig: ConfigurationOptions = {
vulnerability_check: true,
license_check: true,
@@ -30,7 +33,8 @@ const defaultConfig: ConfigurationOptions = {
retry_on_snapshot_warnings: false,
retry_on_snapshot_warnings_timeout: 120,
warn_only: false,
warn_on_openssf_scorecard_level: 3
warn_on_openssf_scorecard_level: 3,
show_openssf_scorecard: false
}
const changesWithEmptyManifests: Changes = [
@@ -72,11 +76,32 @@ const changesWithEmptyManifests: Changes = [
}
]
const scorecard: Scorecard = {
dependencies: [
{
change: {
change_type: 'added',
manifest: '',
ecosystem: 'unknown',
name: 'castore',
version: '0.1.17',
package_url: 'pkg:hex/castore@0.1.17',
license: null,
source_repository_url: null,
scope: 'runtime',
vulnerabilities: []
},
scorecard: null
}
]
}
test('prints headline as h1', () => {
summary.addSummaryToSummary(
emptyChanges,
emptyInvalidLicenseChanges,
emptyChanges,
scorecard,
defaultConfig
)
const text = core.summary.stringify()
@@ -89,6 +114,7 @@ test('only includes "No vulnerabilities or license issues found"-message if both
emptyChanges,
emptyInvalidLicenseChanges,
emptyChanges,
emptyScorecard,
defaultConfig
)
const text = core.summary.stringify()
@@ -102,6 +128,7 @@ test('only includes "No vulnerabilities found"-message if "license_check" is set
emptyChanges,
emptyInvalidLicenseChanges,
emptyChanges,
emptyScorecard,
config
)
const text = core.summary.stringify()
@@ -115,6 +142,7 @@ test('only includes "No license issues found"-message if "vulnerability_check" i
emptyChanges,
emptyInvalidLicenseChanges,
emptyChanges,
emptyScorecard,
config
)
const text = core.summary.stringify()
@@ -127,6 +155,7 @@ test('groups dependencies with empty manifest paths together', () => {
changesWithEmptyManifests,
emptyInvalidLicenseChanges,
emptyChanges,
emptyScorecard,
defaultConfig
)
summary.addScannedDependencies(changesWithEmptyManifests)
@@ -144,6 +173,7 @@ test('does not include status section if nothing was found', () => {
emptyChanges,
emptyInvalidLicenseChanges,
emptyChanges,
emptyScorecard,
defaultConfig
)
const text = core.summary.stringify()
@@ -166,6 +196,7 @@ test('includes count and status icons for all findings', () => {
vulnerabilities,
licenseIssues,
emptyChanges,
emptyScorecard,
defaultConfig
)
@@ -185,6 +216,7 @@ test('uses checkmarks for license issues if only vulnerabilities were found', ()
vulnerabilities,
emptyInvalidLicenseChanges,
emptyChanges,
emptyScorecard,
defaultConfig
)
@@ -208,6 +240,7 @@ test('uses checkmarks for vulnerabilities if only license issues were found', ()
emptyChanges,
licenseIssues,
emptyChanges,
emptyScorecard,
defaultConfig
)

63
dist/index.js generated vendored
View File

@@ -636,7 +636,8 @@ function run() {
core.debug(`Filtered Changes: ${JSON.stringify(filteredChanges)}`);
core.debug(`Config Deny Packages: ${JSON.stringify(config)}`);
const deniedChanges = yield (0, deny_1.getDeniedChanges)(filteredChanges, config.deny_packages, config.deny_groups);
summary.addSummaryToSummary(vulnerableChanges, invalidLicenseChanges, deniedChanges, config);
const scorecard = yield (0, scorecard_1.getScorecardLevels)(filteredChanges);
summary.addSummaryToSummary(vulnerableChanges, invalidLicenseChanges, deniedChanges, scorecard, config);
if (snapshot_warnings) {
summary.addSnapshotWarnings(config, snapshot_warnings);
}
@@ -653,7 +654,6 @@ function run() {
printDeniedDependencies(deniedChanges, config);
}
if (config.show_openssf_scorecard) {
const scorecard = yield (0, scorecard_1.getScorecardLevels)(filteredChanges);
summary.addScorecardToSummary(scorecard, config);
printScorecardBlock(scorecard, config);
createScorecardWarnings(scorecard, config);
@@ -903,8 +903,8 @@ exports.ConfigurationOptionsSchema = z
head_ref: z.string().optional(),
retry_on_snapshot_warnings: z.boolean().default(false),
retry_on_snapshot_warnings_timeout: z.number().default(120),
show_openssf_scorecard: z.boolean().optional(),
warn_on_openssf_scorecard_level: z.number(),
show_openssf_scorecard: z.boolean().optional().default(true),
warn_on_openssf_scorecard_level: z.number().default(3),
comment_summary_in_pr: z
.union([
z.preprocess(val => (val === 'true' ? true : val === 'false' ? false : val), z.boolean()),
@@ -1139,19 +1139,24 @@ const icons = {
cross: '❌',
warning: '⚠️'
};
function addSummaryToSummary(vulnerableChanges, invalidLicenseChanges, deniedChanges, config) {
function addSummaryToSummary(vulnerableChanges, invalidLicenseChanges, deniedChanges, scorecard, config) {
const scorecardWarnings = countScorecardWarnings(scorecard, config);
const licenseIssues = countLicenseIssues(invalidLicenseChanges);
core.summary.addHeading('Dependency Review', 1);
if (vulnerableChanges.length === 0 &&
countLicenseIssues(invalidLicenseChanges) === 0 &&
deniedChanges.length === 0) {
if (!config.license_check) {
core.summary.addRaw(`${icons.check} No vulnerabilities found.`);
}
else if (!config.vulnerability_check) {
core.summary.addRaw(`${icons.check} No license issues found.`);
licenseIssues === 0 &&
deniedChanges.length === 0 &&
scorecardWarnings === 0) {
const issueTypes = [
config.vulnerability_check ? 'vulnerabilities' : '',
config.license_check ? 'license issues' : '',
config.show_openssf_scorecard ? 'OpenSSF Scorecard issues' : ''
];
if (issueTypes.filter(Boolean).length === 0) {
core.summary.addRaw(`${icons.check} No issues found.`);
}
else {
core.summary.addRaw(`${icons.check} No vulnerabilities or license issues found.`);
core.summary.addRaw(`${icons.check} No ${issueTypes.filter(Boolean).join(' or ')} found.`);
}
return;
}
@@ -1174,11 +1179,26 @@ function addSummaryToSummary(vulnerableChanges, invalidLicenseChanges, deniedCha
? [
`${checkOrWarnIcon(deniedChanges.length)} ${deniedChanges.length} package(s) denied.`
]
: []),
...(config.show_openssf_scorecard && scorecardWarnings > 0
? [
`${checkOrWarnIcon(scorecardWarnings)} ${scorecardWarnings ? scorecardWarnings : 'No'} packages with OpenSSF Scorecard issues.`
]
: [])
])
.addRaw('See the Details below.');
}
exports.addSummaryToSummary = addSummaryToSummary;
function countScorecardWarnings(scorecard, config) {
return scorecard.dependencies.reduce((total, dependency) => {
var _a, _b;
return total +
(((_a = dependency.scorecard) === null || _a === void 0 ? void 0 : _a.score) &&
((_b = dependency.scorecard) === null || _b === void 0 ? void 0 : _b.score) < config.warn_on_openssf_scorecard_level
? 1
: 0);
}, 0);
}
function addChangeVulnerabilitiesToSummary(vulnerableChanges, severity) {
if (vulnerableChanges.length === 0) {
return;
@@ -1313,7 +1333,7 @@ function snapshotWarningRecommendation(config, warnings) {
return 'Re-running this action after a short time may resolve the issue.';
}
function addScorecardToSummary(scorecard, config) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
var _a, _b, _c, _d, _e, _f, _g, _h;
core.summary.addHeading('OpenSSF Scorecard', 2);
if (scorecard.dependencies.length > 10) {
core.summary.addRaw(`<details><summary>Scorecard details</summary>`, true);
@@ -1324,20 +1344,19 @@ function addScorecardToSummary(scorecard, config) {
core.debug(`Overall score ${(_a = dependency.scorecard) === null || _a === void 0 ? void 0 : _a.score}`);
// Set the icon based on the overall score value
let overallIcon = '';
if (((_b = dependency.scorecard) === null || _b === void 0 ? void 0 : _b.score) !== undefined &&
((_c = dependency.scorecard) === null || _c === void 0 ? void 0 : _c.score) !== null) {
if ((_b = dependency.scorecard) === null || _b === void 0 ? void 0 : _b.score) {
overallIcon =
((_d = dependency.scorecard) === null || _d === void 0 ? void 0 : _d.score) < config.warn_on_openssf_scorecard_level
((_c = dependency.scorecard) === null || _c === void 0 ? void 0 : _c.score) < config.warn_on_openssf_scorecard_level
? ':warning:'
: ':green_circle:';
}
//Add a row for the dependency
core.summary.addRaw(`<tr><td>${dependency.change.source_repository_url ? `<a href="https://${dependency.change.source_repository_url}">` : ''} ${dependency.change.ecosystem}/${dependency.change.name} ${dependency.change.source_repository_url ? `</a>` : ''}</td><td>${dependency.change.version}</td>
<td>${overallIcon} ${((_e = dependency.scorecard) === null || _e === void 0 ? void 0 : _e.score) === undefined || ((_f = dependency.scorecard) === null || _f === void 0 ? void 0 : _f.score) === null ? 'Unknown' : (_g = dependency.scorecard) === null || _g === void 0 ? void 0 : _g.score}</td>`, false);
<td>${overallIcon} ${((_d = dependency.scorecard) === null || _d === void 0 ? void 0 : _d.score) === undefined || ((_e = dependency.scorecard) === null || _e === void 0 ? void 0 : _e.score) === null ? 'Unknown' : (_f = dependency.scorecard) === null || _f === void 0 ? void 0 : _f.score}</td>`, false);
//Add details table in the last column
if (((_h = dependency.scorecard) === null || _h === void 0 ? void 0 : _h.checks) !== undefined) {
if (((_g = dependency.scorecard) === null || _g === void 0 ? void 0 : _g.checks) !== undefined) {
let detailsTable = '<table><tr><th>Check</th><th>Score</th><th>Reason</th></tr>';
for (const check of ((_j = dependency.scorecard) === null || _j === void 0 ? void 0 : _j.checks) || []) {
for (const check of ((_h = dependency.scorecard) === null || _h === void 0 ? void 0 : _h.checks) || []) {
const icon = parseFloat(check.score) < config.warn_on_openssf_scorecard_level
? ':warning:'
: ':green_circle:';
@@ -50040,8 +50059,8 @@ exports.ConfigurationOptionsSchema = z
head_ref: z.string().optional(),
retry_on_snapshot_warnings: z.boolean().default(false),
retry_on_snapshot_warnings_timeout: z.number().default(120),
show_openssf_scorecard: z.boolean().optional(),
warn_on_openssf_scorecard_level: z.number(),
show_openssf_scorecard: z.boolean().optional().default(true),
warn_on_openssf_scorecard_level: z.number().default(3),
comment_summary_in_pr: z
.union([
z.preprocess(val => (val === 'true' ? true : val === 'false' ? false : val), z.boolean()),

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

View File

@@ -6,7 +6,7 @@
* npx ts-node scripts/create_summary.ts
*/
import {Change, Changes, ConfigurationOptions} from '../src/schemas'
import {Change, Changes, ConfigurationOptions, Scorecard} from '../src/schemas'
import {createTestChange} from '../__tests__/fixtures/create-test-change'
import {InvalidLicenseChanges} from '../src/licenses'
import * as fs from 'fs'
@@ -34,7 +34,28 @@ const defaultConfig: ConfigurationOptions = {
retry_on_snapshot_warnings: false,
retry_on_snapshot_warnings_timeout: 120,
warn_only: false,
warn_on_openssf_scorecard_level: 0
warn_on_openssf_scorecard_level: 3,
show_openssf_scorecard: true
}
const scorecard: Scorecard = {
dependencies: [
{
change: {
change_type: 'added',
manifest: '',
ecosystem: 'unknown',
name: 'castore',
version: '0.1.17',
package_url: 'pkg:hex/castore@0.1.17',
license: null,
source_repository_url: null,
scope: 'runtime',
vulnerabilities: []
},
scorecard: null
}
]
}
const tmpDir = path.resolve(__dirname, '../tmp')
@@ -102,7 +123,13 @@ async function createSummary(
config: ConfigurationOptions,
fileName: string
): Promise<void> {
summary.addSummaryToSummary(vulnerabilities, licenseIssues, denied, config)
summary.addSummaryToSummary(
vulnerabilities,
licenseIssues,
denied,
scorecard,
config
)
summary.addChangeVulnerabilitiesToSummary(
vulnerabilities,
config.fail_on_severity

View File

@@ -1,7 +1,6 @@
import * as core from '@actions/core'
import * as dependencyGraph from './dependency-graph'
import * as github from '@actions/github'
import fs from 'graceful-fs'
import styles from 'ansi-styles'
import {RequestError} from '@octokit/request-error'
import {

View File

@@ -51,8 +51,8 @@ export const ConfigurationOptionsSchema = z
head_ref: z.string().optional(),
retry_on_snapshot_warnings: z.boolean().default(false),
retry_on_snapshot_warnings_timeout: z.number().default(120),
show_openssf_scorecard: z.boolean().optional(),
warn_on_openssf_scorecard_level: z.number(),
show_openssf_scorecard: z.boolean().optional().default(true),
warn_on_openssf_scorecard_level: z.number().default(3),
comment_summary_in_pr: z
.union([
z.preprocess(

View File

@@ -37,7 +37,7 @@ export function addSummaryToSummary(
core.summary.addRaw(`${icons.check} No issues found.`)
} else {
core.summary.addRaw(
`No ${issueTypes.filter(Boolean).join(' or ')} found.`
`${icons.check} No ${issueTypes.filter(Boolean).join(' or ')} found.`
)
}