build and package scope filtering
This commit is contained in:
@@ -38,7 +38,7 @@ jobs:
|
|||||||
|
|
||||||
### GitHub Enterprise Server
|
### GitHub Enterprise Server
|
||||||
|
|
||||||
This action is available in GHES starting with version 3.6. Make sure
|
This action is available in Enterprise Server starting with version 3.6. Make sure
|
||||||
[GitHub Advanced
|
[GitHub Advanced
|
||||||
Security](https://docs.github.com/en/[email protected]/admin/code-security/managing-github-advanced-security-for-your-enterprise/enabling-github-advanced-security-for-your-enterprise)
|
Security](https://docs.github.com/en/[email protected]/admin/code-security/managing-github-advanced-security-for-your-enterprise/enabling-github-advanced-security-for-your-enterprise)
|
||||||
and [GitHub
|
and [GitHub
|
||||||
@@ -92,7 +92,7 @@ jobs:
|
|||||||
# base-ref: ${{ github.event.pull_request.base.ref }}
|
# base-ref: ${{ github.event.pull_request.base.ref }}
|
||||||
# head-ref: ${{ github.event.pull_request.head.ref }}
|
# head-ref: ${{ github.event.pull_request.head.ref }}
|
||||||
#
|
#
|
||||||
# You can only include one of these two options: `allow-licenses` and `deny-licenses`. These options are not supported on GHES.
|
# You can only include one of these two options: `allow-licenses` and `deny-licenses`. These options are not supported on Enterprise Server.
|
||||||
#
|
#
|
||||||
# Possible values: Any `spdx_id` value(s) from https://docs.github.com/en/rest/licenses
|
# Possible values: Any `spdx_id` value(s) from https://docs.github.com/en/rest/licenses
|
||||||
# allow-licenses: GPL-3.0, BSD-3-Clause, MIT
|
# allow-licenses: GPL-3.0, BSD-3-Clause, MIT
|
||||||
@@ -124,7 +124,7 @@ This example will only fail on pull requests with `critical` and `high` vulnerab
|
|||||||
|
|
||||||
### Dependency Scoping
|
### Dependency Scoping
|
||||||
|
|
||||||
By default the action will only fail on `runtime` dependencies that have vulnerabilities or unacceptable licenses, ignoring `development` dependencies. You can override this behavior with the `fail-on-scopes` option, which will allow you to list the specific dependency scopes you care about. The possible values are: `unknown`, `runtime`, and `development`. Note: Filtering by scope will not be supported on GHES just yet, as the REST API's introduction of `scope` will be released in an upcoming version. We will treat all dependencies on GHES as having a `runtime` scope and thus will not be filtered away.
|
By default the action will only fail on `runtime` dependencies that have vulnerabilities or unacceptable licenses, ignoring `development` dependencies. You can override this behavior with the `fail-on-scopes` option, which will allow you to list the specific dependency scopes you care about. The possible values are: `unknown`, `runtime`, and `development`. Note: Filtering by scope will not be supported on Enterprise Server just yet, as the REST API's introduction of `scope` will be released in an upcoming Enterprise Server version. We will treat all dependencies on Enterprise Server as having a `runtime` scope and thus will not be filtered away.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Dependency Review
|
- name: Dependency Review
|
||||||
@@ -138,7 +138,7 @@ By default the action will only fail on `runtime` dependencies that have vulnera
|
|||||||
You can set the action to fail on pull requests based on the licenses of the dependencies
|
You can set the action to fail on pull requests based on the licenses of the dependencies
|
||||||
they introduce. With `allow-licenses` you can define the list of licenses
|
they introduce. With `allow-licenses` you can define the list of licenses
|
||||||
your repository will accept. Alternatively, you can use `deny-licenses` to only
|
your repository will accept. Alternatively, you can use `deny-licenses` to only
|
||||||
forbid a subset of licenses. These options are not supported on GHES.
|
forbid a subset of licenses. These options are not supported on Enterprise Server.
|
||||||
|
|
||||||
You can use the [Licenses
|
You can use the [Licenses
|
||||||
API](https://docs.github.com/en/rest/licenses) to see the full list of
|
API](https://docs.github.com/en/rest/licenses) to see the full list of
|
||||||
@@ -163,7 +163,7 @@ to filter. A couple of examples:
|
|||||||
|
|
||||||
**Important**
|
**Important**
|
||||||
|
|
||||||
- Checking for licenses is not supported on GHES.
|
- Checking for licenses is not supported on Enterprise Server.
|
||||||
- The action will only accept one of the two parameters; an error will
|
- The action will only accept one of the two parameters; an error will
|
||||||
be raised if you provide both.
|
be raised if you provide both.
|
||||||
- By default both parameters are empty (no license checking is
|
- By default both parameters are empty (no license checking is
|
||||||
|
|||||||
+39
-9
@@ -220,10 +220,12 @@ function run() {
|
|||||||
allow: config.allow_licenses,
|
allow: config.allow_licenses,
|
||||||
deny: config.deny_licenses
|
deny: config.deny_licenses
|
||||||
};
|
};
|
||||||
const addedChanges = (0, filter_1.filterChangesBySeverity)(minSeverity, changes).filter(change => change.change_type === 'added' &&
|
const scopes = config.fail_on_scopes;
|
||||||
|
const scopedChanges = (0, filter_1.filterChangesByScopes)(scopes, changes);
|
||||||
|
const addedChanges = (0, filter_1.filterChangesBySeverity)(minSeverity, scopedChanges).filter(change => change.change_type === 'added' &&
|
||||||
change.vulnerabilities !== undefined &&
|
change.vulnerabilities !== undefined &&
|
||||||
change.vulnerabilities.length > 0);
|
change.vulnerabilities.length > 0);
|
||||||
const [licenseErrors, unknownLicenses] = (0, licenses_1.getDeniedLicenseChanges)(changes, licenses);
|
const [licenseErrors, unknownLicenses] = (0, licenses_1.getDeniedLicenseChanges)(scopedChanges, licenses);
|
||||||
summary.addSummaryToSummary(addedChanges, licenseErrors, unknownLicenses);
|
summary.addSummaryToSummary(addedChanges, licenseErrors, unknownLicenses);
|
||||||
if (addedChanges.length > 0) {
|
if (addedChanges.length > 0) {
|
||||||
for (const change of addedChanges) {
|
for (const change of addedChanges) {
|
||||||
@@ -333,9 +335,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.ChangesSchema = exports.ConfigurationOptionsSchema = exports.PullRequestSchema = exports.ChangeSchema = exports.SEVERITIES = void 0;
|
exports.ChangesSchema = exports.ConfigurationOptionsSchema = exports.PullRequestSchema = exports.ChangeSchema = exports.SCOPES = exports.SEVERITIES = void 0;
|
||||||
const z = __importStar(__nccwpck_require__(3301));
|
const z = __importStar(__nccwpck_require__(3301));
|
||||||
exports.SEVERITIES = ['critical', 'high', 'moderate', 'low'];
|
exports.SEVERITIES = ['critical', 'high', 'moderate', 'low'];
|
||||||
|
exports.SCOPES = ['unknown', 'runtime', 'development'];
|
||||||
exports.ChangeSchema = z.object({
|
exports.ChangeSchema = z.object({
|
||||||
change_type: z.enum(['added', 'removed']),
|
change_type: z.enum(['added', 'removed']),
|
||||||
manifest: z.string(),
|
manifest: z.string(),
|
||||||
@@ -345,9 +348,10 @@ exports.ChangeSchema = z.object({
|
|||||||
package_url: z.string(),
|
package_url: z.string(),
|
||||||
license: z.string().nullable(),
|
license: z.string().nullable(),
|
||||||
source_repository_url: z.string().nullable(),
|
source_repository_url: z.string().nullable(),
|
||||||
|
scope: z.enum(exports.SCOPES).optional(),
|
||||||
vulnerabilities: z
|
vulnerabilities: z
|
||||||
.array(z.object({
|
.array(z.object({
|
||||||
severity: z.enum(['critical', 'high', 'moderate', 'low']),
|
severity: z.enum(exports.SEVERITIES),
|
||||||
advisory_ghsa_id: z.string(),
|
advisory_ghsa_id: z.string(),
|
||||||
advisory_summary: z.string(),
|
advisory_summary: z.string(),
|
||||||
advisory_url: z.string()
|
advisory_url: z.string()
|
||||||
@@ -363,6 +367,7 @@ exports.PullRequestSchema = z.object({
|
|||||||
exports.ConfigurationOptionsSchema = z
|
exports.ConfigurationOptionsSchema = z
|
||||||
.object({
|
.object({
|
||||||
fail_on_severity: z.enum(exports.SEVERITIES).default('low'),
|
fail_on_severity: z.enum(exports.SEVERITIES).default('low'),
|
||||||
|
fail_on_scopes: z.array(z.enum(exports.SCOPES)).default(['runtime']),
|
||||||
allow_licenses: z.array(z.string()).default([]),
|
allow_licenses: z.array(z.string()).default([]),
|
||||||
deny_licenses: z.array(z.string()).default([]),
|
deny_licenses: z.array(z.string()).default([]),
|
||||||
base_ref: z.string(),
|
base_ref: z.string(),
|
||||||
@@ -14928,11 +14933,23 @@ function getOptionalInput(name) {
|
|||||||
const value = core.getInput(name);
|
const value = core.getInput(name);
|
||||||
return value.length > 0 ? value : undefined;
|
return value.length > 0 ? value : undefined;
|
||||||
}
|
}
|
||||||
|
function parseList(list) {
|
||||||
|
if (list === undefined) {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return list.split(',').map(x => x.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
function readConfig() {
|
function readConfig() {
|
||||||
const fail_on_severity = z
|
const fail_on_severity = z
|
||||||
.enum(schemas_1.SEVERITIES)
|
.enum(schemas_1.SEVERITIES)
|
||||||
.default('low')
|
.default('low')
|
||||||
.parse(getOptionalInput('fail-on-severity'));
|
.parse(getOptionalInput('fail-on-severity'));
|
||||||
|
const fail_on_scopes = z
|
||||||
|
.array(z.enum(schemas_1.SCOPES))
|
||||||
|
.default(['runtime'])
|
||||||
|
.parse(parseList(getOptionalInput('fail-on-scopes')));
|
||||||
const allow_licenses = getOptionalInput('allow-licenses');
|
const allow_licenses = getOptionalInput('allow-licenses');
|
||||||
const deny_licenses = getOptionalInput('deny-licenses');
|
const deny_licenses = getOptionalInput('deny-licenses');
|
||||||
if (allow_licenses !== undefined && deny_licenses !== undefined) {
|
if (allow_licenses !== undefined && deny_licenses !== undefined) {
|
||||||
@@ -14942,8 +14959,9 @@ function readConfig() {
|
|||||||
const head_ref = getOptionalInput('head-ref');
|
const head_ref = getOptionalInput('head-ref');
|
||||||
return {
|
return {
|
||||||
fail_on_severity,
|
fail_on_severity,
|
||||||
allow_licenses: allow_licenses === null || allow_licenses === void 0 ? void 0 : allow_licenses.split(',').map(x => x.trim()),
|
fail_on_scopes,
|
||||||
deny_licenses: deny_licenses === null || deny_licenses === void 0 ? void 0 : deny_licenses.split(',').map(x => x.trim()),
|
allow_licenses: parseList(allow_licenses),
|
||||||
|
deny_licenses: parseList(deny_licenses),
|
||||||
base_ref,
|
base_ref,
|
||||||
head_ref
|
head_ref
|
||||||
};
|
};
|
||||||
@@ -14959,7 +14977,7 @@ exports.readConfig = readConfig;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.filterChangesBySeverity = void 0;
|
exports.filterChangesByScopes = exports.filterChangesBySeverity = void 0;
|
||||||
const schemas_1 = __nccwpck_require__(1129);
|
const schemas_1 = __nccwpck_require__(1129);
|
||||||
function filterChangesBySeverity(severity, changes) {
|
function filterChangesBySeverity(severity, changes) {
|
||||||
const severityIdx = schemas_1.SEVERITIES.indexOf(severity);
|
const severityIdx = schemas_1.SEVERITIES.indexOf(severity);
|
||||||
@@ -14983,6 +15001,15 @@ function filterChangesBySeverity(severity, changes) {
|
|||||||
return filteredChanges;
|
return filteredChanges;
|
||||||
}
|
}
|
||||||
exports.filterChangesBySeverity = filterChangesBySeverity;
|
exports.filterChangesBySeverity = filterChangesBySeverity;
|
||||||
|
function filterChangesByScopes(scopes, changes) {
|
||||||
|
const filteredChanges = changes.filter(change => {
|
||||||
|
// if there is no scope on the change (Enterprise Server API for now), we will assume it is a runtime scope
|
||||||
|
const scope = change.scope || 'runtime';
|
||||||
|
return scopes.includes(scope);
|
||||||
|
});
|
||||||
|
return filteredChanges;
|
||||||
|
}
|
||||||
|
exports.filterChangesByScopes = filterChangesByScopes;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -15016,9 +15043,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.ChangesSchema = exports.ConfigurationOptionsSchema = exports.PullRequestSchema = exports.ChangeSchema = exports.SEVERITIES = void 0;
|
exports.ChangesSchema = exports.ConfigurationOptionsSchema = exports.PullRequestSchema = exports.ChangeSchema = exports.SCOPES = exports.SEVERITIES = void 0;
|
||||||
const z = __importStar(__nccwpck_require__(3301));
|
const z = __importStar(__nccwpck_require__(3301));
|
||||||
exports.SEVERITIES = ['critical', 'high', 'moderate', 'low'];
|
exports.SEVERITIES = ['critical', 'high', 'moderate', 'low'];
|
||||||
|
exports.SCOPES = ['unknown', 'runtime', 'development'];
|
||||||
exports.ChangeSchema = z.object({
|
exports.ChangeSchema = z.object({
|
||||||
change_type: z.enum(['added', 'removed']),
|
change_type: z.enum(['added', 'removed']),
|
||||||
manifest: z.string(),
|
manifest: z.string(),
|
||||||
@@ -15028,9 +15056,10 @@ exports.ChangeSchema = z.object({
|
|||||||
package_url: z.string(),
|
package_url: z.string(),
|
||||||
license: z.string().nullable(),
|
license: z.string().nullable(),
|
||||||
source_repository_url: z.string().nullable(),
|
source_repository_url: z.string().nullable(),
|
||||||
|
scope: z.enum(exports.SCOPES).optional(),
|
||||||
vulnerabilities: z
|
vulnerabilities: z
|
||||||
.array(z.object({
|
.array(z.object({
|
||||||
severity: z.enum(['critical', 'high', 'moderate', 'low']),
|
severity: z.enum(exports.SEVERITIES),
|
||||||
advisory_ghsa_id: z.string(),
|
advisory_ghsa_id: z.string(),
|
||||||
advisory_summary: z.string(),
|
advisory_summary: z.string(),
|
||||||
advisory_url: z.string()
|
advisory_url: z.string()
|
||||||
@@ -15046,6 +15075,7 @@ exports.PullRequestSchema = z.object({
|
|||||||
exports.ConfigurationOptionsSchema = z
|
exports.ConfigurationOptionsSchema = z
|
||||||
.object({
|
.object({
|
||||||
fail_on_severity: z.enum(exports.SEVERITIES).default('low'),
|
fail_on_severity: z.enum(exports.SEVERITIES).default('low'),
|
||||||
|
fail_on_scopes: z.array(z.enum(exports.SCOPES)).default(['runtime']),
|
||||||
allow_licenses: z.array(z.string()).default([]),
|
allow_licenses: z.array(z.string()).default([]),
|
||||||
deny_licenses: z.array(z.string()).default([]),
|
deny_licenses: z.array(z.string()).default([]),
|
||||||
base_ref: z.string(),
|
base_ref: z.string(),
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
+2
-4
@@ -39,11 +39,9 @@ export function filterChangesByScopes(
|
|||||||
changes: Changes
|
changes: Changes
|
||||||
): Changes {
|
): Changes {
|
||||||
const filteredChanges = changes.filter(change => {
|
const filteredChanges = changes.filter(change => {
|
||||||
// if there is no scope on the change (GHES API for now), we will assume it is a runtime scope
|
// if there is no scope on the change (Enterprise Server API for now), we will assume it is a runtime scope
|
||||||
const scope = change.scope || 'runtime'
|
const scope = change.scope || 'runtime'
|
||||||
if (scopes.includes(scope)) {
|
return scopes.includes(scope)
|
||||||
return true
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return filteredChanges
|
return filteredChanges
|
||||||
|
|||||||
Reference in New Issue
Block a user