Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add none as option for fail-on-severity #432

Merged
merged 25 commits into from Feb 11, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -82,11 +82,15 @@ Configure this action by either inlining these options in your workflow file, or
| `deny-groups` | Any number of groups (namespaces) to block in a PR. | Namespace(s) in [purl](https://github.com/package-url/purl-spec) format (no package name, no version number) | empty |
| `retry-on-snapshot-warnings`\* | Enable or disable retrying the action every 10 seconds while waiting for dependency submission actions to complete. | `true`, `false` | `false` |
| `retry-on-snapshot-warnings-timeout`\* | Maximum amount of time (in seconds) to retry the action while waiting for dependency submission actions to complete. | Any positive integer | 120 |
| `warn-only`+ | Enable or disable the action to fail, when set to `true` the action will log all vulnarabilities as warning. | `true`, `false` | `false` |
tgrall marked this conversation as resolved.
Show resolved Hide resolved

\*not supported for use with GitHub Enterprise Server

†will be supported with GitHub Enterprise Server 3.8

+when `warn-only` is set to `true`, all vulnarabilities, independently of the severity, will be reported as warnings and the action will not fail.
tgrall marked this conversation as resolved.
Show resolved Hide resolved


### Inline Configuration

You can pass options to the Dependency Review GitHub Action using your workflow file.
Expand Down
5 changes: 5 additions & 0 deletions __tests__/config.test.ts
Expand Up @@ -26,6 +26,11 @@ test('it reads custom configs', async () => {
expect(config.allow_licenses).toEqual(['BSD', 'GPL 2'])
})

test('it defaults to false for warn-only', async () => {
const config = await readConfig()
expect(config.warn_only).toEqual(false)
})

test('it defaults to empty allow/deny lists ', async () => {
const config = await readConfig()

Expand Down
3 changes: 2 additions & 1 deletion __tests__/summary.test.ts
Expand Up @@ -28,7 +28,8 @@ const defaultConfig: ConfigurationOptions = {
deny_groups: [],
comment_summary_in_pr: true,
retry_on_snapshot_warnings: false,
retry_on_snapshot_warnings_timeout: 120
retry_on_snapshot_warnings_timeout: 120,
warn_only: false
}

const changesWithEmptyManifests: Changes = [
Expand Down
3 changes: 2 additions & 1 deletion __tests__/test-helpers.ts
Expand Up @@ -18,7 +18,8 @@ export function clearInputs(): void {
'CONFIG-FILE',
'BASE-REF',
'HEAD-REF',
'COMMENT-SUMMARY-IN-PR'
'COMMENT-SUMMARY-IN-PR',
'WARN-ONLY',
]

// eslint-disable-next-line github/array-foreach
Expand Down
5 changes: 5 additions & 0 deletions action.yml
Expand Up @@ -61,6 +61,11 @@ inputs:
description: Number of seconds to wait before stopping snapshot retries.
required: false
default: 120
warn-only:
description: When set to `true` this action will not make the action to fail, this override the `fail-on-severity` parameter.
tgrall marked this conversation as resolved.
Show resolved Hide resolved
required: false
default: false

runs:
using: 'node20'
main: 'dist/index.js'
48 changes: 35 additions & 13 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion scripts/create_summary.ts
Expand Up @@ -32,7 +32,8 @@ const defaultConfig: ConfigurationOptions = {
],
comment_summary_in_pr: true,
retry_on_snapshot_warnings: false,
retry_on_snapshot_warnings_timeout: 120
retry_on_snapshot_warnings_timeout: 120,
warn_only: false
}

const tmpDir = path.resolve(__dirname, '../tmp')
Expand Down
4 changes: 3 additions & 1 deletion src/config.ts
Expand Up @@ -47,6 +47,7 @@ function readInlineConfig(): ConfigurationOptionsPartial {
const retry_on_snapshot_warnings_timeout = getOptionalNumber(
'retry-on-snapshot-warnings-timeout'
)
const warn_only = getOptionalBoolean('warn-only')

validatePURL(allow_dependencies_licenses)
validateLicenses('allow-licenses', allow_licenses)
Expand All @@ -67,7 +68,8 @@ function readInlineConfig(): ConfigurationOptionsPartial {
head_ref,
comment_summary_in_pr,
retry_on_snapshot_warnings,
retry_on_snapshot_warnings_timeout
retry_on_snapshot_warnings_timeout,
warn_only
}

return Object.fromEntries(
Expand Down
39 changes: 29 additions & 10 deletions src/main.ts
Expand Up @@ -87,7 +87,14 @@ async function run(): Promise<void> {
scopedChanges
)

const minSeverity = config.fail_on_severity
const failOnSeverityParams = config.fail_on_severity
const warnOnly = config.warn_only
let minSeverity: Severity = 'low'
// If failOnSeverityParams is not set or warnOnly is true, the minSeverity is low, to allow all vulnerabilities to be reported as warnings
if (failOnSeverityParams && !warnOnly) {
minSeverity = failOnSeverityParams
}

const vulnerableChanges = filterChangesBySeverity(
minSeverity,
filteredChanges
Expand Down Expand Up @@ -124,11 +131,11 @@ async function run(): Promise<void> {

if (config.vulnerability_check) {
summary.addChangeVulnerabilitiesToSummary(vulnerableChanges, minSeverity)
printVulnerabilitiesBlock(vulnerableChanges, minSeverity)
printVulnerabilitiesBlock(vulnerableChanges, minSeverity, warnOnly)
}
if (config.license_check) {
summary.addLicensesToSummary(invalidLicenseChanges, config)
printLicensesBlock(invalidLicenseChanges)
printLicensesBlock(invalidLicenseChanges, warnOnly)
}
if (config.deny_packages || config.deny_groups) {
summary.addDeniedToSummary(deniedChanges)
Expand Down Expand Up @@ -167,19 +174,25 @@ async function run(): Promise<void> {

function printVulnerabilitiesBlock(
addedChanges: Changes,
minSeverity: Severity
minSeverity: Severity,
warnOnly: 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 (warnOnly) {
core.warning(msg)
} else {
core.setFailed(msg)
}
} else {
core.info(
`Dependency review did not detect any vulnerable packages with severity level "${minSeverity}" or higher.`
Expand All @@ -202,13 +215,19 @@ function printChangeVulnerabilities(change: Change): void {
}

function printLicensesBlock(
invalidLicenseChanges: Record<string, Changes>
invalidLicenseChanges: Record<string, Changes>,
warnOnly: 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 (warnOnly) {
core.warning(msg)
} else {
core.setFailed(msg)
}
}
if (invalidLicenseChanges.unresolved.length > 0) {
core.warning(
Expand Down
3 changes: 2 additions & 1 deletion src/schemas.ts
Expand Up @@ -59,7 +59,8 @@ export const ConfigurationOptionsSchema = z
),
z.enum(['always', 'never', 'on-failure'])
])
.default('never')
.default('never'),
warn_only: z.boolean().default(false)
})
.transform(config => {
if (config.comment_summary_in_pr === true) {
Expand Down