Refactor types, add printing

This commit is contained in:
Justin Hutchings
2024-03-03 05:24:07 +00:00
parent 72d5b06a68
commit ffd129c285
6 changed files with 211 additions and 128 deletions

View File

@@ -65,6 +65,10 @@ inputs:
description: When set to `true` this action will always complete with success, overriding the `fail-on-severity` parameter.
required: false
default: false
warn-on-openssf-scorecard-threshold:
description: Numeric threshold for the OpenSSF Scorecard score. If the score is below this threshold, the action will warn you.
required: false
default: 0
outputs:
comment-content:
description: Prepared dependency report comment

184
dist/index.js generated vendored
View File

@@ -654,6 +654,8 @@ function run() {
summary.addDeniedToSummary(deniedChanges);
printDeniedDependencies(deniedChanges, config);
}
//summary.addScorecardToSummary(scorecard, config)
printScorecardBlock(scorecard, config);
summary.addScannedDependencies(changes);
printScannedDependencies(changes);
yield (0, comment_pr_1.commentPr)(core.summary, config);
@@ -743,6 +745,15 @@ function printNullLicenses(changes) {
core.info(`${ansi_styles_1.default.bold.open}${change.manifest} » ${change.name}@${change.version}${ansi_styles_1.default.bold.close}`);
}
}
function printScorecardBlock(scorecard, config) {
core.group('Scorecard', () => __awaiter(this, void 0, void 0, function* () {
if (scorecard) {
for (const dependency of scorecard.dependencies) {
core.info(`${dependency.ecosystem}/${dependency.packageName}: OpenSSF Scorecard Score: ${dependency.depsDevData.scorecard.overallScore}`);
}
}
}));
}
function renderSeverity(severity) {
const color = {
critical: 'red',
@@ -824,7 +835,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.DepsDevProjectSchema = exports.ComparisonResponseSchema = exports.ChangesSchema = exports.ConfigurationOptionsSchema = exports.PullRequestSchema = exports.ChangeSchema = exports.SeveritySchema = exports.SCOPES = exports.SEVERITIES = void 0;
exports.ScorecardSchema = exports.DepsDevProjectSchema = exports.ComparisonResponseSchema = exports.ChangesSchema = exports.ConfigurationOptionsSchema = exports.PullRequestSchema = exports.ChangeSchema = exports.SeveritySchema = exports.SCOPES = exports.SEVERITIES = void 0;
const z = __importStar(__nccwpck_require__(3301));
exports.SEVERITIES = ['critical', 'high', 'moderate', 'low'];
exports.SCOPES = ['unknown', 'runtime', 'development'];
@@ -916,43 +927,51 @@ exports.ComparisonResponseSchema = z.object({
});
exports.DepsDevProjectSchema = z.object({
projectKey: z.object({
id: z.string({}),
openIssuesCount: z.string(),
starsCount: z.string(),
forksCount: z.string(),
license: z.string(),
description: z.string(),
homepage: z.string(),
scorecard: z.object({
date: z.string(),
repository: z.object({
name: z.string(),
commit: z.string()
}),
scorecard: z.object({
version: z.string(),
commit: z.string()
}),
checks: z.array(z.object({
name: z.string(),
documentation: z.object({
shortDescription: z.string(),
url: z.string()
}),
score: z.string(),
reason: z.string(),
details: z.array(z.string())
})),
overallScore: z.number()
id: z.string({})
}),
openIssuesCount: z.string(),
starsCount: z.string(),
forksCount: z.string(),
license: z.string(),
description: z.string(),
homepage: z.string(),
scorecard: z.object({
date: z.string(),
repository: z.object({
name: z.string(),
commit: z.string()
}),
ossFuzz: z.object({
lineCount: z.string(),
lineCoverCount: z.string(),
date: z.string(),
configUrl: z.string()
})
scorecard: z.object({
version: z.string(),
commit: z.string()
}),
checks: z.array(z.object({
name: z.string(),
documentation: z.object({
shortDescription: z.string(),
url: z.string()
}),
score: z.string(),
reason: z.string(),
details: z.array(z.string())
})),
overallScore: z.number()
}),
ossFuzz: z.object({
lineCount: z.string(),
lineCoverCount: z.string(),
date: z.string(),
configUrl: z.string()
})
});
exports.ScorecardSchema = z.object({
dependencies: z.array(z.object({
ecosystem: z.string(),
packageName: z.string(),
version: z.string().nullish(),
depsDevData: exports.DepsDevProjectSchema
}))
});
/***/ }),
@@ -996,23 +1015,24 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getScorecardLevels = void 0;
const schemas_1 = __nccwpck_require__(8774);
const packageurl_js_1 = __nccwpck_require__(8915);
const core = __importStar(__nccwpck_require__(2186));
function getScorecardLevels(changes) {
return __awaiter(this, void 0, void 0, function* () {
const data = { dependencies: [] };
const data = {};
for (const change of changes) {
try {
const purl = packageurl_js_1.PackageURL.fromString(change.package_url);
const ecosystem = purl.type;
const packageName = purl.name;
const version = purl.version;
const depsDevResponse = yield getDepsDevData(ecosystem, packageName, version);
data.dependencies.push({
purl: purl,
ecosystem: ecosystem,
packageName: packageName,
version: version,
depsDevData: yield getDepsDevData(ecosystem, packageName, version)
ecosystem,
packageName,
version,
depsDevData: depsDevResponse
});
}
catch (error) {
@@ -1044,7 +1064,7 @@ function getDepsDevData(ecosystem, packageName, version) {
catch (error) {
core.debug(`Error fetching data: ${error.message}`);
}
return {};
return schemas_1.DepsDevProjectSchema.parse({});
});
}
function getDepsDevProjectData(projectKeyId) {
@@ -1064,7 +1084,7 @@ function getDepsDevProjectData(projectKeyId) {
catch (error) {
core.debug(`Error fetching project data: ${error.message}`);
}
return {};
return schemas_1.DepsDevProjectSchema.parse({});
});
}
@@ -49914,7 +49934,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.DepsDevProjectSchema = exports.ComparisonResponseSchema = exports.ChangesSchema = exports.ConfigurationOptionsSchema = exports.PullRequestSchema = exports.ChangeSchema = exports.SeveritySchema = exports.SCOPES = exports.SEVERITIES = void 0;
exports.ScorecardSchema = exports.DepsDevProjectSchema = exports.ComparisonResponseSchema = exports.ChangesSchema = exports.ConfigurationOptionsSchema = exports.PullRequestSchema = exports.ChangeSchema = exports.SeveritySchema = exports.SCOPES = exports.SEVERITIES = void 0;
const z = __importStar(__nccwpck_require__(3301));
exports.SEVERITIES = ['critical', 'high', 'moderate', 'low'];
exports.SCOPES = ['unknown', 'runtime', 'development'];
@@ -50006,43 +50026,51 @@ exports.ComparisonResponseSchema = z.object({
});
exports.DepsDevProjectSchema = z.object({
projectKey: z.object({
id: z.string({}),
openIssuesCount: z.string(),
starsCount: z.string(),
forksCount: z.string(),
license: z.string(),
description: z.string(),
homepage: z.string(),
scorecard: z.object({
date: z.string(),
repository: z.object({
name: z.string(),
commit: z.string()
}),
scorecard: z.object({
version: z.string(),
commit: z.string()
}),
checks: z.array(z.object({
name: z.string(),
documentation: z.object({
shortDescription: z.string(),
url: z.string()
}),
score: z.string(),
reason: z.string(),
details: z.array(z.string())
})),
overallScore: z.number()
id: z.string({})
}),
openIssuesCount: z.string(),
starsCount: z.string(),
forksCount: z.string(),
license: z.string(),
description: z.string(),
homepage: z.string(),
scorecard: z.object({
date: z.string(),
repository: z.object({
name: z.string(),
commit: z.string()
}),
ossFuzz: z.object({
lineCount: z.string(),
lineCoverCount: z.string(),
date: z.string(),
configUrl: z.string()
})
scorecard: z.object({
version: z.string(),
commit: z.string()
}),
checks: z.array(z.object({
name: z.string(),
documentation: z.object({
shortDescription: z.string(),
url: z.string()
}),
score: z.string(),
reason: z.string(),
details: z.array(z.string())
})),
overallScore: z.number()
}),
ossFuzz: z.object({
lineCount: z.string(),
lineCoverCount: z.string(),
date: z.string(),
configUrl: z.string()
})
});
exports.ScorecardSchema = z.object({
dependencies: z.array(z.object({
ecosystem: z.string(),
packageName: z.string(),
version: z.string().nullish(),
depsDevData: exports.DepsDevProjectSchema
}))
});
/***/ }),

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

View File

@@ -3,7 +3,14 @@ import * as dependencyGraph from './dependency-graph'
import * as github from '@actions/github'
import styles from 'ansi-styles'
import {RequestError} from '@octokit/request-error'
import {Change, Severity, Changes, ConfigurationOptions} from './schemas'
import {
Change,
Severity,
Changes,
ConfigurationOptions,
Scorecard,
DepsDevProject
} from './schemas'
import {readConfig} from '../src/config'
import {
filterChangesBySeverity,
@@ -145,6 +152,8 @@ async function run(): Promise<void> {
summary.addDeniedToSummary(deniedChanges)
printDeniedDependencies(deniedChanges, config)
}
//summary.addScorecardToSummary(scorecard, config)
printScorecardBlock(scorecard, config)
summary.addScannedDependencies(changes)
printScannedDependencies(changes)
@@ -261,6 +270,21 @@ function printNullLicenses(changes: Changes): void {
}
}
function printScorecardBlock(
scorecard: Scorecard,
config: ConfigurationOptions
): void {
core.group('Scorecard', async () => {
if (scorecard) {
for (const dependency of scorecard.dependencies) {
core.info(
`${dependency.ecosystem}/${dependency.packageName}: OpenSSF Scorecard Score: ${dependency.depsDevData.scorecard.overallScore}`
)
}
}
})
}
function renderSeverity(
severity: 'critical' | 'high' | 'moderate' | 'low'
): string {

View File

@@ -102,46 +102,57 @@ export const ComparisonResponseSchema = z.object({
export const DepsDevProjectSchema = z.object({
projectKey: z.object({
id: z.string({}),
openIssuesCount: z.string(),
starsCount: z.string(),
forksCount: z.string(),
license: z.string(),
description: z.string(),
homepage: z.string(),
scorecard: z.object({
date: z.string(),
repository: z.object({
name: z.string(),
commit: z.string()
}),
scorecard: z.object({
version: z.string(),
commit: z.string()
}),
checks: z.array(
z.object({
name: z.string(),
documentation: z.object({
shortDescription: z.string(),
url: z.string()
}),
score: z.string(),
reason: z.string(),
details: z.array(z.string())
})
),
overallScore: z.number()
id: z.string({})
}),
openIssuesCount: z.string(),
starsCount: z.string(),
forksCount: z.string(),
license: z.string(),
description: z.string(),
homepage: z.string(),
scorecard: z.object({
date: z.string(),
repository: z.object({
name: z.string(),
commit: z.string()
}),
ossFuzz: z.object({
lineCount: z.string(),
lineCoverCount: z.string(),
date: z.string(),
configUrl: z.string()
})
scorecard: z.object({
version: z.string(),
commit: z.string()
}),
checks: z.array(
z.object({
name: z.string(),
documentation: z.object({
shortDescription: z.string(),
url: z.string()
}),
score: z.string(),
reason: z.string(),
details: z.array(z.string())
})
),
overallScore: z.number()
}),
ossFuzz: z.object({
lineCount: z.string(),
lineCoverCount: z.string(),
date: z.string(),
configUrl: z.string()
})
})
export const ScorecardSchema = z.object({
dependencies: z.array(
z.object({
ecosystem: z.string(),
packageName: z.string(),
version: z.string().nullish(),
depsDevData: DepsDevProjectSchema
})
)
})
export type Change = z.infer<typeof ChangeSchema>
export type Changes = z.infer<typeof ChangesSchema>
export type ComparisonResponse = z.infer<typeof ComparisonResponseSchema>
@@ -149,3 +160,4 @@ export type ConfigurationOptions = z.infer<typeof ConfigurationOptionsSchema>
export type Severity = z.infer<typeof SeveritySchema>
export type Scope = (typeof SCOPES)[number]
export type DepsDevProject = z.infer<typeof DepsDevProjectSchema>
export type Scorecard = z.infer<typeof ScorecardSchema>

View File

@@ -1,23 +1,36 @@
import {Change, Changes, DepsDevProject, DepsDevProjectSchema} from './schemas'
import {
Change,
Changes,
DepsDevProject,
DepsDevProjectSchema,
Scorecard,
ScorecardSchema
} from './schemas'
import {isSPDXValid, octokitClient} from './utils'
import {PackageURL} from 'packageurl-js'
import * as core from '@actions/core'
export async function getScorecardLevels(changes: Change[]): Promise<object> {
const data: any = {dependencies: []}
export async function getScorecardLevels(
changes: Change[]
): Promise<Scorecard> {
const data: Scorecard = {} as Scorecard
for (const change of changes) {
try {
const purl = PackageURL.fromString(change.package_url)
const ecosystem = purl.type
const packageName = purl.name
const version = purl.version
const depsDevResponse: DepsDevProject = await getDepsDevData(
ecosystem,
packageName,
version
)
data.dependencies.push({
purl: purl,
ecosystem: ecosystem,
packageName: packageName,
version: version,
depsDevData: await getDepsDevData(ecosystem, packageName, version)
ecosystem,
packageName,
version,
depsDevData: depsDevResponse
})
} catch (error: any) {
core.debug(`Error parsing package url: ${error.message}`)
@@ -32,7 +45,7 @@ async function getDepsDevData(
ecosystem: String,
packageName: String,
version: any
): Promise<object> {
): Promise<DepsDevProject> {
try {
core.debug(`Getting deps.dev data for ${packageName} ${version}`)
const url = `${depsDevAPIRoot}//v3alpha/systems/${ecosystem}/packages/${packageName}/versions/${version}`
@@ -51,10 +64,12 @@ async function getDepsDevData(
} catch (error: any) {
core.debug(`Error fetching data: ${error.message}`)
}
return {}
return DepsDevProjectSchema.parse({})
}
async function getDepsDevProjectData(projectKeyId: string): Promise<object> {
async function getDepsDevProjectData(
projectKeyId: string
): Promise<DepsDevProject> {
try {
core.debug(`Getting deps.dev project data for ${projectKeyId}`)
const url = `${depsDevAPIRoot}/v3alpha/projects/${encodeURIComponent(projectKeyId)}`
@@ -70,5 +85,5 @@ async function getDepsDevProjectData(projectKeyId: string): Promise<object> {
} catch (error: any) {
core.debug(`Error fetching project data: ${error.message}`)
}
return {}
return DepsDevProjectSchema.parse({})
}