Add none as option for fail-on-severity
This commit is contained in:
@@ -68,7 +68,7 @@ Configure this action by either inlining these options in your workflow file, or
|
||||
|
||||
| Option | Usage | Possible values | Default value |
|
||||
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ------------- |
|
||||
| `fail-on-severity` | Defines the threshold for the level of severity. The action will fail on any pull requests that introduce vulnerabilities of the specified severity level or higher. | `low`, `moderate`, `high`, `critical` | `low` |
|
||||
| `fail-on-severity` | Defines the threshold for the level of severity. The action will fail on any pull requests that introduce vulnerabilities of the specified severity level or higher. | `low`, `moderate`, `high`, `critical`, `none`+ | `low` |
|
||||
| `allow-licenses`* | Contains a list of allowed licenses. The action will fail on pull requests that introduce dependencies with licenses that do not match the list. | Any [SPDX-compliant identifier(s)](https://spdx.org/licenses/) | none |
|
||||
| `deny-licenses`* | Contains a list of prohibited licenses. The action will fail on pull requests that introduce dependencies with licenses that match the list. | Any [SPDX-compliant identifier(s)](https://spdx.org/licenses/) | none |
|
||||
| `fail-on-scopes`† | Contains a list of strings of the build environments you want to support. The action will fail on pull requests that introduce vulnerabilities in the scopes that match the list. | `runtime`, `development`, `unknown` | `runtime` |
|
||||
@@ -82,6 +82,8 @@ Configure this action by either inlining these options in your workflow file, or
|
||||
|
||||
†will be supported with GitHub Enterprise Server 3.8
|
||||
|
||||
+when `fail-on-severity` is set to `none`, the action will not fail on any vulnerabilities or invalid licenses. This is useful if you want to use the action to generate a report of vulnerabilities and invalid licenses, but not fail the workflow.
|
||||
|
||||
### Inline Configuration
|
||||
|
||||
You can pass options to the Dependency Review GitHub Action using your workflow file.
|
||||
|
||||
@@ -54,6 +54,13 @@ test('it reads custom configs', async () => {
|
||||
expect(config.allow_licenses).toEqual(['BSD', 'GPL 2'])
|
||||
})
|
||||
|
||||
test('it defaults to none severity', async () => {
|
||||
setInput('fail-on-severity', 'none')
|
||||
const config = await readConfig()
|
||||
expect(config.fail_on_severity).toEqual('none')
|
||||
})
|
||||
|
||||
|
||||
test('it defaults to empty allow/deny lists ', async () => {
|
||||
const config = await readConfig()
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ inputs:
|
||||
required: false
|
||||
default: ${{ github.token }}
|
||||
fail-on-severity:
|
||||
description: Don't block PRs below this severity. Possible values are `low`, `moderate`, `high`, `critical`.
|
||||
description: Don't block PRs below this severity. Possible values are `low`, `moderate`, `high`, `critical`, `none`.
|
||||
required: false
|
||||
default: 'low'
|
||||
fail-on-scopes:
|
||||
|
||||
51
dist/index.js
generated
vendored
51
dist/index.js
generated
vendored
@@ -462,7 +462,13 @@ function run() {
|
||||
core.info('No Dependency Changes found. Skipping Dependency Review.');
|
||||
return;
|
||||
}
|
||||
const minSeverity = config.fail_on_severity;
|
||||
// config.fail_on_severity
|
||||
const failOnSeverityParams = config.fail_on_severity;
|
||||
const failOnVulnerability = (config.fail_on_severity != 'none');
|
||||
let minSeverity = 'low';
|
||||
if (failOnSeverityParams != 'none') {
|
||||
minSeverity = failOnSeverityParams;
|
||||
}
|
||||
const scopedChanges = (0, filter_1.filterChangesByScopes)(config.fail_on_scopes, changes);
|
||||
const filteredChanges = (0, filter_1.filterAllowedAdvisories)(config.allow_ghsas, scopedChanges);
|
||||
const vulnerableChanges = (0, filter_1.filterChangesBySeverity)(minSeverity, filteredChanges).filter(change => change.change_type === 'added' &&
|
||||
@@ -475,11 +481,11 @@ function run() {
|
||||
summary.addSummaryToSummary(vulnerableChanges, invalidLicenseChanges, config);
|
||||
if (config.vulnerability_check) {
|
||||
summary.addChangeVulnerabilitiesToSummary(vulnerableChanges, minSeverity);
|
||||
printVulnerabilitiesBlock(vulnerableChanges, minSeverity);
|
||||
printVulnerabilitiesBlock(vulnerableChanges, minSeverity, failOnVulnerability);
|
||||
}
|
||||
if (config.license_check) {
|
||||
summary.addLicensesToSummary(invalidLicenseChanges, config);
|
||||
printLicensesBlock(invalidLicenseChanges);
|
||||
printLicensesBlock(invalidLicenseChanges, failOnVulnerability);
|
||||
}
|
||||
summary.addScannedDependencies(changes);
|
||||
printScannedDependencies(changes);
|
||||
@@ -508,17 +514,24 @@ function run() {
|
||||
}
|
||||
});
|
||||
}
|
||||
function printVulnerabilitiesBlock(addedChanges, minSeverity) {
|
||||
let failed = false;
|
||||
function printVulnerabilitiesBlock(addedChanges, minSeverity, failOnVulnerability) {
|
||||
let vulFound = false;
|
||||
core.group('Vulnerabilities', () => __awaiter(this, void 0, void 0, function* () {
|
||||
if (addedChanges.length > 0) {
|
||||
for (const change of addedChanges) {
|
||||
printChangeVulnerabilities(change);
|
||||
}
|
||||
failed = true;
|
||||
vulFound = true;
|
||||
}
|
||||
if (failed) {
|
||||
core.setFailed('Dependency review detected vulnerable packages.');
|
||||
if (vulFound) {
|
||||
const msg = 'Dependency review detected vulnerable packages.';
|
||||
if (failOnVulnerability) {
|
||||
const msg = 'Dependency review detected vulnerable packages.';
|
||||
core.setFailed(msg);
|
||||
}
|
||||
else {
|
||||
core.warning(msg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
core.info(`Dependency review did not detect any vulnerable packages with severity level "${minSeverity}" or higher.`);
|
||||
@@ -531,12 +544,18 @@ function printChangeVulnerabilities(change) {
|
||||
core.info(` ↪ ${vuln.advisory_url}`);
|
||||
}
|
||||
}
|
||||
function printLicensesBlock(invalidLicenseChanges) {
|
||||
function printLicensesBlock(invalidLicenseChanges, failOnVulnerability) {
|
||||
core.group('Licenses', () => __awaiter(this, void 0, void 0, function* () {
|
||||
if (invalidLicenseChanges.forbidden.length > 0) {
|
||||
core.info('\nThe following dependencies have incompatible licenses:');
|
||||
printLicensesError(invalidLicenseChanges.forbidden);
|
||||
core.setFailed('Dependency review detected incompatible licenses.');
|
||||
const msg = 'Dependency review detected incompatible licenses.';
|
||||
if (failOnVulnerability) {
|
||||
core.setFailed(msg);
|
||||
}
|
||||
else {
|
||||
core.warning(msg);
|
||||
}
|
||||
}
|
||||
if (invalidLicenseChanges.unresolved.length > 0) {
|
||||
core.warning('\nThe validity of the licenses of the dependencies below could not be determined. Ensure that they are valid SPDX licenses:');
|
||||
@@ -630,10 +649,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.ChangesSchema = exports.ConfigurationOptionsSchema = exports.PullRequestSchema = exports.ChangeSchema = exports.SeveritySchema = exports.SCOPES = exports.SEVERITIES = void 0;
|
||||
exports.ChangesSchema = exports.ConfigurationOptionsSchema = exports.PullRequestSchema = exports.ChangeSchema = exports.SeveritySchema = exports.FailOnSeveritySchema = exports.SCOPES = exports.SEVERITIES = exports.FAIL_ON_SEVERITIES = void 0;
|
||||
const z = __importStar(__nccwpck_require__(3301));
|
||||
exports.FAIL_ON_SEVERITIES = ['critical', 'high', 'moderate', 'low', 'none'];
|
||||
exports.SEVERITIES = ['critical', 'high', 'moderate', 'low'];
|
||||
exports.SCOPES = ['unknown', 'runtime', 'development'];
|
||||
exports.FailOnSeveritySchema = z.enum(exports.FAIL_ON_SEVERITIES).default('low');
|
||||
exports.SeveritySchema = z.enum(exports.SEVERITIES).default('low');
|
||||
exports.ChangeSchema = z.object({
|
||||
change_type: z.enum(['added', 'removed']),
|
||||
@@ -662,7 +683,7 @@ exports.PullRequestSchema = z.object({
|
||||
});
|
||||
exports.ConfigurationOptionsSchema = z
|
||||
.object({
|
||||
fail_on_severity: exports.SeveritySchema,
|
||||
fail_on_severity: exports.FailOnSeveritySchema,
|
||||
fail_on_scopes: z.array(z.enum(exports.SCOPES)).default(['runtime']),
|
||||
allow_licenses: z.array(z.string()).optional(),
|
||||
deny_licenses: z.array(z.string()).optional(),
|
||||
@@ -45083,10 +45104,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.ChangesSchema = exports.ConfigurationOptionsSchema = exports.PullRequestSchema = exports.ChangeSchema = exports.SeveritySchema = exports.SCOPES = exports.SEVERITIES = void 0;
|
||||
exports.ChangesSchema = exports.ConfigurationOptionsSchema = exports.PullRequestSchema = exports.ChangeSchema = exports.SeveritySchema = exports.FailOnSeveritySchema = exports.SCOPES = exports.SEVERITIES = exports.FAIL_ON_SEVERITIES = void 0;
|
||||
const z = __importStar(__nccwpck_require__(3301));
|
||||
exports.FAIL_ON_SEVERITIES = ['critical', 'high', 'moderate', 'low', 'none'];
|
||||
exports.SEVERITIES = ['critical', 'high', 'moderate', 'low'];
|
||||
exports.SCOPES = ['unknown', 'runtime', 'development'];
|
||||
exports.FailOnSeveritySchema = z.enum(exports.FAIL_ON_SEVERITIES).default('low');
|
||||
exports.SeveritySchema = z.enum(exports.SEVERITIES).default('low');
|
||||
exports.ChangeSchema = z.object({
|
||||
change_type: z.enum(['added', 'removed']),
|
||||
@@ -45115,7 +45138,7 @@ exports.PullRequestSchema = z.object({
|
||||
});
|
||||
exports.ConfigurationOptionsSchema = z
|
||||
.object({
|
||||
fail_on_severity: exports.SeveritySchema,
|
||||
fail_on_severity: exports.FailOnSeveritySchema,
|
||||
fail_on_scopes: z.array(z.enum(exports.SCOPES)).default(['runtime']),
|
||||
allow_licenses: z.array(z.string()).optional(),
|
||||
deny_licenses: z.array(z.string()).optional(),
|
||||
|
||||
2
dist/index.js.map
generated
vendored
2
dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
41
src/main.ts
41
src/main.ts
@@ -3,7 +3,7 @@ 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} from './schemas'
|
||||
import {Change, Severity, Changes, FailOnSeverity} from './schemas'
|
||||
import {readConfig} from '../src/config'
|
||||
import {
|
||||
filterChangesBySeverity,
|
||||
@@ -33,8 +33,14 @@ async function run(): Promise<void> {
|
||||
core.info('No Dependency Changes found. Skipping Dependency Review.')
|
||||
return
|
||||
}
|
||||
// config.fail_on_severity
|
||||
const failOnSeverityParams = config.fail_on_severity
|
||||
const failOnVulnerability = (config.fail_on_severity != 'none')
|
||||
let minSeverity: Severity = 'low'
|
||||
if (failOnSeverityParams != 'none') {
|
||||
minSeverity = failOnSeverityParams
|
||||
}
|
||||
|
||||
const minSeverity = config.fail_on_severity
|
||||
const scopedChanges = filterChangesByScopes(config.fail_on_scopes, changes)
|
||||
const filteredChanges = filterAllowedAdvisories(
|
||||
config.allow_ghsas,
|
||||
@@ -67,11 +73,11 @@ async function run(): Promise<void> {
|
||||
|
||||
if (config.vulnerability_check) {
|
||||
summary.addChangeVulnerabilitiesToSummary(vulnerableChanges, minSeverity)
|
||||
printVulnerabilitiesBlock(vulnerableChanges, minSeverity)
|
||||
printVulnerabilitiesBlock(vulnerableChanges, minSeverity, failOnVulnerability)
|
||||
}
|
||||
if (config.license_check) {
|
||||
summary.addLicensesToSummary(invalidLicenseChanges, config)
|
||||
printLicensesBlock(invalidLicenseChanges)
|
||||
printLicensesBlock(invalidLicenseChanges, failOnVulnerability)
|
||||
}
|
||||
|
||||
summary.addScannedDependencies(changes)
|
||||
@@ -102,19 +108,26 @@ async function run(): Promise<void> {
|
||||
|
||||
function printVulnerabilitiesBlock(
|
||||
addedChanges: Changes,
|
||||
minSeverity: Severity
|
||||
minSeverity: Severity,
|
||||
failOnVulnerability: boolean
|
||||
): void {
|
||||
let failed = false
|
||||
let vulFound = false
|
||||
core.group('Vulnerabilities', async () => {
|
||||
if (addedChanges.length > 0) {
|
||||
for (const change of addedChanges) {
|
||||
printChangeVulnerabilities(change)
|
||||
}
|
||||
failed = true
|
||||
vulFound = true
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
core.setFailed('Dependency review detected vulnerable packages.')
|
||||
if (vulFound) {
|
||||
const msg = 'Dependency review detected vulnerable packages.'
|
||||
if (failOnVulnerability) {
|
||||
const msg = 'Dependency review detected vulnerable packages.'
|
||||
core.setFailed(msg)
|
||||
} else {
|
||||
core.warning(msg)
|
||||
}
|
||||
} else {
|
||||
core.info(
|
||||
`Dependency review did not detect any vulnerable packages with severity level "${minSeverity}" or higher.`
|
||||
@@ -137,13 +150,19 @@ function printChangeVulnerabilities(change: Change): void {
|
||||
}
|
||||
|
||||
function printLicensesBlock(
|
||||
invalidLicenseChanges: Record<string, Changes>
|
||||
invalidLicenseChanges: Record<string, Changes>,
|
||||
failOnVulnerability: boolean
|
||||
): void {
|
||||
core.group('Licenses', async () => {
|
||||
if (invalidLicenseChanges.forbidden.length > 0) {
|
||||
core.info('\nThe following dependencies have incompatible licenses:')
|
||||
printLicensesError(invalidLicenseChanges.forbidden)
|
||||
core.setFailed('Dependency review detected incompatible licenses.')
|
||||
const msg = 'Dependency review detected incompatible licenses.';
|
||||
if (failOnVulnerability) {
|
||||
core.setFailed(msg)
|
||||
} else {
|
||||
core.warning(msg)
|
||||
}
|
||||
}
|
||||
if (invalidLicenseChanges.unresolved.length > 0) {
|
||||
core.warning(
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import * as z from 'zod'
|
||||
|
||||
export const FAIL_ON_SEVERITIES = ['critical', 'high', 'moderate', 'low', 'none'] as const
|
||||
export const SEVERITIES = ['critical', 'high', 'moderate', 'low'] as const
|
||||
export const SCOPES = ['unknown', 'runtime', 'development'] as const
|
||||
|
||||
export const FailOnSeveritySchema = z.enum(FAIL_ON_SEVERITIES).default('low')
|
||||
export const SeveritySchema = z.enum(SEVERITIES).default('low')
|
||||
|
||||
export const ChangeSchema = z.object({
|
||||
@@ -36,7 +38,7 @@ export const PullRequestSchema = z.object({
|
||||
|
||||
export const ConfigurationOptionsSchema = z
|
||||
.object({
|
||||
fail_on_severity: SeveritySchema,
|
||||
fail_on_severity: FailOnSeveritySchema,
|
||||
fail_on_scopes: z.array(z.enum(SCOPES)).default(['runtime']),
|
||||
allow_licenses: z.array(z.string()).optional(),
|
||||
deny_licenses: z.array(z.string()).optional(),
|
||||
@@ -77,5 +79,6 @@ export const ChangesSchema = z.array(ChangeSchema)
|
||||
export type Change = z.infer<typeof ChangeSchema>
|
||||
export type Changes = z.infer<typeof ChangesSchema>
|
||||
export type ConfigurationOptions = z.infer<typeof ConfigurationOptionsSchema>
|
||||
export type FailOnSeverity = z.infer<typeof FailOnSeveritySchema>
|
||||
export type Severity = z.infer<typeof SeveritySchema>
|
||||
export type Scope = (typeof SCOPES)[number]
|
||||
|
||||
Reference in New Issue
Block a user