Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e58c696e52 | |||
| 9b7c72ddcd | |||
| 7dcfabfea2 | |||
| 5f0808ffb1 | |||
| fcc66c23b3 | |||
| 1dd418bcb3 | |||
| 640617990f | |||
| 2034babb6b | |||
| 7e773b1e98 | |||
| a3460920cc | |||
| 0659a74c94 |
@@ -54,6 +54,28 @@ test('it raises an error if an empty allow list is specified', async () => {
|
||||
)
|
||||
})
|
||||
|
||||
test('it raises an error when an invalid package-url is used for deny-packages', async () => {
|
||||
setInput('deny-packages', 'not-a-purl')
|
||||
|
||||
await expect(readConfig()).rejects.toThrow(`Error parsing package-url`)
|
||||
})
|
||||
|
||||
test('it raises an error when a nameless package-url is used for deny-packages', async () => {
|
||||
setInput('deny-packages', 'pkg:npm/@namespace/')
|
||||
|
||||
await expect(readConfig()).rejects.toThrow(
|
||||
`Error parsing package-url: name is required`
|
||||
)
|
||||
})
|
||||
|
||||
test('it raises an error when an argument to deny-groups is missing a namespace', async () => {
|
||||
setInput('deny-groups', 'pkg:npm/my-fun-org')
|
||||
|
||||
await expect(readConfig()).rejects.toThrow(
|
||||
`package-url must have a namespace`
|
||||
)
|
||||
})
|
||||
|
||||
test('it raises an error when given an unknown severity', async () => {
|
||||
setInput('fail-on-severity', 'zombies')
|
||||
|
||||
|
||||
@@ -106,6 +106,25 @@ test('denies packages that match the deny group list exactly', async () => {
|
||||
expect(deniedChanges[0]).toBe(changes[1])
|
||||
})
|
||||
|
||||
test(`denies packages using the namespace from the name when there's no package_url`, async () => {
|
||||
const changes: Changes = [
|
||||
createTestChange({
|
||||
package_url: 'pkg:npm/org.test.pass/pass-this@1.0.0',
|
||||
ecosystem: 'npm'
|
||||
}),
|
||||
createTestChange({
|
||||
name: 'org.test:deny-this',
|
||||
package_url: '',
|
||||
ecosystem: 'maven'
|
||||
})
|
||||
]
|
||||
const deniedGroups = createTestPURLs(['pkg:maven/org.test/'])
|
||||
const deniedChanges = await getDeniedChanges(changes, [], deniedGroups)
|
||||
|
||||
expect(deniedChanges.length).toEqual(1)
|
||||
expect(deniedChanges[0]).toBe(changes[1])
|
||||
})
|
||||
|
||||
test('allows packages not defined in the deny packages and groups list', async () => {
|
||||
const changes: Changes = [npmChange, pipChange]
|
||||
const deniedPackages = createTestPURLs([
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {PackageURL} from 'packageurl-js'
|
||||
import {Change} from '../../src/schemas'
|
||||
import {createTestVulnerability} from './create-test-vulnerability'
|
||||
import {parsePURL} from '../../src/utils'
|
||||
import {PackageURL, parsePURL} from '../../src/purl'
|
||||
|
||||
const defaultNpmChange: Change = {
|
||||
change_type: 'added',
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
import {expect, test} from '@jest/globals'
|
||||
import {parsePURL} from '../src/purl'
|
||||
|
||||
test('parsePURL returns an error if the purl does not start with "pkg:"', () => {
|
||||
const purl = 'not-a-purl'
|
||||
const result = parsePURL(purl)
|
||||
expect(result.error).toEqual('package-url must start with "pkg:"')
|
||||
})
|
||||
|
||||
test('parsePURL returns an error if the purl does not contain a type', () => {
|
||||
const purl = 'pkg:/'
|
||||
const result = parsePURL(purl)
|
||||
expect(result.error).toEqual('package-url must contain a type')
|
||||
})
|
||||
|
||||
test('parsePURL returns an error if the purl does not contain a namespace or name', () => {
|
||||
const purl = 'pkg:ecosystem/'
|
||||
const result = parsePURL(purl)
|
||||
expect(result.type).toEqual('ecosystem')
|
||||
expect(result.error).toEqual('package-url must contain a namespace or name')
|
||||
})
|
||||
|
||||
test('parsePURL returns a PURL with the correct values in the happy case', () => {
|
||||
const purl = 'pkg:ecosystem/namespace/name@version'
|
||||
const result = parsePURL(purl)
|
||||
expect(result.type).toEqual('ecosystem')
|
||||
expect(result.namespace).toEqual('namespace')
|
||||
expect(result.name).toEqual('name')
|
||||
expect(result.version).toEqual('version')
|
||||
expect(result.original).toEqual(purl)
|
||||
expect(result.error).toBeNull()
|
||||
})
|
||||
|
||||
test('parsePURL table test', () => {
|
||||
const examples = [
|
||||
{
|
||||
purl: 'pkg:npm/@n4m3SPACE/Name@^1.2.3',
|
||||
expected: {
|
||||
type: 'npm',
|
||||
namespace: '@n4m3SPACE',
|
||||
name: 'Name',
|
||||
version: '^1.2.3',
|
||||
original: 'pkg:npm/@n4m3SPACE/Name@^1.2.3',
|
||||
error: null
|
||||
}
|
||||
},
|
||||
{
|
||||
purl: 'pkg:npm/%40ns%20foo/n%40me@1.%2f2.3',
|
||||
expected: {
|
||||
type: 'npm',
|
||||
namespace: '@ns foo',
|
||||
name: 'n@me',
|
||||
version: '1./2.3',
|
||||
original: 'pkg:npm/%40ns%20foo/n%40me@1.%2f2.3',
|
||||
error: null
|
||||
}
|
||||
},
|
||||
{
|
||||
purl: 'pkg:ecosystem/name@version',
|
||||
expected: {
|
||||
type: 'ecosystem',
|
||||
namespace: null,
|
||||
name: 'name',
|
||||
version: 'version',
|
||||
original: 'pkg:ecosystem/name@version',
|
||||
error: null
|
||||
}
|
||||
},
|
||||
{
|
||||
purl: 'pkg:npm/namespace/',
|
||||
expected: {
|
||||
type: 'npm',
|
||||
namespace: 'namespace',
|
||||
name: null,
|
||||
version: null,
|
||||
original: 'pkg:npm/namespace/',
|
||||
error: null
|
||||
}
|
||||
},
|
||||
{
|
||||
purl: 'pkg:ecosystem/name',
|
||||
expected: {
|
||||
type: 'ecosystem',
|
||||
namespace: null,
|
||||
name: 'name',
|
||||
version: null,
|
||||
original: 'pkg:ecosystem/name',
|
||||
error: null
|
||||
}
|
||||
},
|
||||
{
|
||||
purl: 'pkg:/?',
|
||||
expected: {
|
||||
type: '',
|
||||
namespace: null,
|
||||
name: null,
|
||||
version: null,
|
||||
original: 'pkg:/?',
|
||||
error: 'package-url must contain a type'
|
||||
}
|
||||
},
|
||||
{
|
||||
purl: 'pkg:ecosystem/#',
|
||||
expected: {
|
||||
type: 'ecosystem',
|
||||
namespace: null,
|
||||
name: null,
|
||||
version: null,
|
||||
original: 'pkg:ecosystem/#',
|
||||
error: 'package-url must contain a namespace or name'
|
||||
}
|
||||
},
|
||||
{
|
||||
purl: 'pkg:ecosystem/name@version#subpath?attributes=123',
|
||||
expected: {
|
||||
type: 'ecosystem',
|
||||
namespace: null,
|
||||
name: 'name',
|
||||
version: 'version',
|
||||
original: 'pkg:ecosystem/name@version#subpath?attributes=123',
|
||||
error: null
|
||||
}
|
||||
},
|
||||
{
|
||||
purl: 'pkg:ecosystem/name@version#subpath',
|
||||
expected: {
|
||||
type: 'ecosystem',
|
||||
namespace: null,
|
||||
name: 'name',
|
||||
version: 'version',
|
||||
original: 'pkg:ecosystem/name@version#subpath',
|
||||
error: null
|
||||
}
|
||||
},
|
||||
{
|
||||
purl: 'pkg:ecosystem/namespace/name@version?attributes',
|
||||
expected: {
|
||||
type: 'ecosystem',
|
||||
namespace: 'namespace',
|
||||
name: 'name',
|
||||
version: 'version',
|
||||
original: 'pkg:ecosystem/namespace/name@version?attributes',
|
||||
error: null
|
||||
}
|
||||
},
|
||||
{
|
||||
purl: 'pkg:ecosystem/name#subpath?attributes',
|
||||
expected: {
|
||||
type: 'ecosystem',
|
||||
namespace: null,
|
||||
name: 'name',
|
||||
version: null,
|
||||
original: 'pkg:ecosystem/name#subpath?attributes',
|
||||
error: null
|
||||
}
|
||||
}
|
||||
]
|
||||
for (const example of examples) {
|
||||
const result = parsePURL(example.purl)
|
||||
expect(result).toEqual(example.expected)
|
||||
}
|
||||
})
|
||||
@@ -19,7 +19,9 @@ export function clearInputs(): void {
|
||||
'BASE-REF',
|
||||
'HEAD-REF',
|
||||
'COMMENT-SUMMARY-IN-PR',
|
||||
'WARN-ONLY'
|
||||
'WARN-ONLY',
|
||||
'DENY-GROUPS',
|
||||
'DENY-PACKAGES'
|
||||
]
|
||||
|
||||
// eslint-disable-next-line github/array-foreach
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ inputs:
|
||||
description: A comma-separated list of package URLs to deny (e.g. "pkg:npm/express, pkg:pypi/pycrypto"). If version specified, only deny matching packages and version; else, deny all regardless of version.
|
||||
required: false
|
||||
deny-groups:
|
||||
description: A comma-separated list of package URLs for group(s)/namespace(s) to deny (e.g. "pkg:npm/express, pkg:pypi/pycrypto")
|
||||
description: A comma-separated list of package URLs for group(s)/namespace(s) to deny (e.g. "pkg:npm/express/, pkg:pypi/pycrypto/"). Please note that the group name must be followed by a `/`.
|
||||
required: false
|
||||
retry-on-snapshot-warnings:
|
||||
description: Whether to retry on snapshot warnings
|
||||
|
||||
+330
-351
@@ -177,25 +177,27 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.getDeniedChanges = void 0;
|
||||
exports.getNamespace = exports.getDeniedChanges = void 0;
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
const packageurl_js_1 = __nccwpck_require__(8915);
|
||||
const purl_1 = __nccwpck_require__(3609);
|
||||
function getDeniedChanges(changes_1) {
|
||||
return __awaiter(this, arguments, void 0, function* (changes, deniedPackages = [], deniedGroups = []) {
|
||||
const changesDenied = [];
|
||||
let hasDeniedPackage = false;
|
||||
for (const change of changes) {
|
||||
const changedPackage = packageurl_js_1.PackageURL.fromString(change.package_url);
|
||||
for (const denied of deniedPackages) {
|
||||
if ((!denied.version || changedPackage.version === denied.version) &&
|
||||
changedPackage.name === denied.name) {
|
||||
if ((!denied.version || change.version === denied.version) &&
|
||||
change.name === denied.name) {
|
||||
changesDenied.push(change);
|
||||
hasDeniedPackage = true;
|
||||
}
|
||||
}
|
||||
for (const denied of deniedGroups) {
|
||||
if (changedPackage.namespace &&
|
||||
changedPackage.namespace === denied.namespace) {
|
||||
const namespace = (0, exports.getNamespace)(change);
|
||||
if (!denied.namespace) {
|
||||
core.error(`Denied group represented by '${denied.original}' does not have a namespace. The format should be 'pkg:<type>/<namespace>/'.`);
|
||||
}
|
||||
if (namespace && namespace === denied.namespace) {
|
||||
changesDenied.push(change);
|
||||
hasDeniedPackage = true;
|
||||
}
|
||||
@@ -211,6 +213,17 @@ function getDeniedChanges(changes_1) {
|
||||
});
|
||||
}
|
||||
exports.getDeniedChanges = getDeniedChanges;
|
||||
const getNamespace = (change) => {
|
||||
if (change.package_url) {
|
||||
return (0, purl_1.parsePURL)(change.package_url).namespace;
|
||||
}
|
||||
const matches = change.name.match(/([^:/]+)[:/]/);
|
||||
if (matches && matches.length > 1) {
|
||||
return matches[1];
|
||||
}
|
||||
return null;
|
||||
};
|
||||
exports.getNamespace = getNamespace;
|
||||
|
||||
|
||||
/***/ }),
|
||||
@@ -354,13 +367,13 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.getInvalidLicenseChanges = void 0;
|
||||
const spdx_satisfies_1 = __importDefault(__nccwpck_require__(4424));
|
||||
const utils_1 = __nccwpck_require__(918);
|
||||
const packageurl_js_1 = __nccwpck_require__(8915);
|
||||
const purl_1 = __nccwpck_require__(3609);
|
||||
function getInvalidLicenseChanges(changes, licenses) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
var _a;
|
||||
const { allow, deny } = licenses;
|
||||
const licenseExclusions = (_a = licenses.licenseExclusions) === null || _a === void 0 ? void 0 : _a.map((pkgUrl) => {
|
||||
return packageurl_js_1.PackageURL.fromString(encodeURI(pkgUrl));
|
||||
return (0, purl_1.parsePURL)(pkgUrl);
|
||||
});
|
||||
const groupedChanges = yield groupChanges(changes);
|
||||
// Takes the changes from the groupedChanges object and filters out the ones that are part of the exclusions list
|
||||
@@ -369,7 +382,7 @@ function getInvalidLicenseChanges(changes, licenses) {
|
||||
if (change.package_url.length === 0) {
|
||||
return true;
|
||||
}
|
||||
const changeAsPackageURL = packageurl_js_1.PackageURL.fromString(encodeURI(change.package_url));
|
||||
const changeAsPackageURL = (0, purl_1.parsePURL)(encodeURI(change.package_url));
|
||||
// We want to find if the licenseExclussion list contains the PackageURL of the Change
|
||||
// If it does, we want to filter it out and therefore return false
|
||||
// If it doesn't, we want to keep it and therefore return true
|
||||
@@ -827,6 +840,105 @@ function createScorecardWarnings(scorecards, config) {
|
||||
run();
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 3609:
|
||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.parsePURL = exports.PurlSchema = void 0;
|
||||
const z = __importStar(__nccwpck_require__(3301));
|
||||
// the basic purl type, containing type, namespace, name, and version.
|
||||
// other than type, all fields are nullable. this is for maximum flexibility
|
||||
// at the cost of strict adherence to the package-url spec.
|
||||
exports.PurlSchema = z.object({
|
||||
type: z.string(),
|
||||
namespace: z.string().nullable(),
|
||||
name: z.string().nullable(), // name is nullable for deny-groups
|
||||
version: z.string().nullable(),
|
||||
original: z.string(),
|
||||
error: z.string().nullable()
|
||||
});
|
||||
const PURL_TYPE = /pkg:([a-zA-Z0-9-_]+)\/.*/;
|
||||
function parsePURL(purl) {
|
||||
const result = {
|
||||
type: '',
|
||||
namespace: null,
|
||||
name: null,
|
||||
version: null,
|
||||
original: purl,
|
||||
error: null
|
||||
};
|
||||
if (!purl.startsWith('pkg:')) {
|
||||
result.error = 'package-url must start with "pkg:"';
|
||||
return result;
|
||||
}
|
||||
const type = purl.match(PURL_TYPE);
|
||||
if (!type) {
|
||||
result.error = 'package-url must contain a type';
|
||||
return result;
|
||||
}
|
||||
result.type = type[1];
|
||||
const parts = purl.split('/');
|
||||
// the first 'part' should be 'pkg:ecosystem'
|
||||
if (parts.length < 2 || !parts[1]) {
|
||||
result.error = 'package-url must contain a namespace or name';
|
||||
return result;
|
||||
}
|
||||
let namePlusRest;
|
||||
if (parts.length === 2) {
|
||||
namePlusRest = parts[1];
|
||||
}
|
||||
else {
|
||||
result.namespace = decodeURIComponent(parts[1]);
|
||||
namePlusRest = parts[2];
|
||||
}
|
||||
const name = namePlusRest.match(/([^@#?]+)[@#?]?.*/);
|
||||
if (!result.namespace && !name) {
|
||||
result.error = 'package-url must contain a namespace or name';
|
||||
return result;
|
||||
}
|
||||
if (!name) {
|
||||
// we're done here
|
||||
return result;
|
||||
}
|
||||
result.name = decodeURIComponent(name[1]);
|
||||
const version = namePlusRest.match(/@([^#?]+)[#?]?.*/);
|
||||
if (!version) {
|
||||
return result;
|
||||
}
|
||||
result.version = decodeURIComponent(version[1]);
|
||||
// we don't parse subpath or attributes, so we're done here
|
||||
return result;
|
||||
}
|
||||
exports.parsePURL = parsePURL;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 8774:
|
||||
@@ -860,12 +972,47 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.ScorecardSchema = exports.ScorecardApiSchema = exports.ComparisonResponseSchema = exports.ChangesSchema = exports.ConfigurationOptionsSchema = exports.PullRequestSchema = exports.ChangeSchema = exports.SeveritySchema = exports.SCOPES = exports.SEVERITIES = void 0;
|
||||
const z = __importStar(__nccwpck_require__(3301));
|
||||
const utils_1 = __nccwpck_require__(918);
|
||||
const purl_1 = __nccwpck_require__(3609);
|
||||
exports.SEVERITIES = ['critical', 'high', 'moderate', 'low'];
|
||||
exports.SCOPES = ['unknown', 'runtime', 'development'];
|
||||
exports.SeveritySchema = z.enum(exports.SEVERITIES).default('low');
|
||||
const PackageURL = z.string().transform(purlString => {
|
||||
return (0, utils_1.parsePURL)(purlString);
|
||||
const PackageURL = z
|
||||
.string()
|
||||
.transform(purlString => {
|
||||
return (0, purl_1.parsePURL)(purlString);
|
||||
})
|
||||
.superRefine((purl, context) => {
|
||||
if (purl.error) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Error parsing package-url: ${purl.error}`
|
||||
});
|
||||
}
|
||||
if (!purl.name) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Error parsing package-url: name is required`
|
||||
});
|
||||
}
|
||||
});
|
||||
const PackageURLWithNamespace = z
|
||||
.string()
|
||||
.transform(purlString => {
|
||||
return (0, purl_1.parsePURL)(purlString);
|
||||
})
|
||||
.superRefine((purl, context) => {
|
||||
if (purl.error) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Error parsing purl: ${purl.error}`
|
||||
});
|
||||
}
|
||||
if (purl.namespace === null) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `package-url must have a namespace, and the namespace must be followed by '/'`
|
||||
});
|
||||
}
|
||||
});
|
||||
exports.ChangeSchema = z.object({
|
||||
change_type: z.enum(['added', 'removed']),
|
||||
@@ -901,7 +1048,7 @@ exports.ConfigurationOptionsSchema = z
|
||||
allow_dependencies_licenses: z.array(z.string()).optional(),
|
||||
allow_ghsas: z.array(z.string()).default([]),
|
||||
deny_packages: z.array(PackageURL).default([]),
|
||||
deny_groups: z.array(PackageURL).default([]),
|
||||
deny_groups: z.array(PackageURLWithNamespace).default([]),
|
||||
license_check: z.boolean().default(true),
|
||||
vulnerability_check: z.boolean().default(true),
|
||||
config_file: z.string().optional(),
|
||||
@@ -1455,11 +1602,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.parsePURL = exports.octokitClient = exports.isSPDXValid = exports.renderUrl = exports.getManifestsSet = exports.groupDependenciesByManifest = void 0;
|
||||
exports.octokitClient = exports.isSPDXValid = exports.renderUrl = exports.getManifestsSet = exports.groupDependenciesByManifest = void 0;
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
const octokit_1 = __nccwpck_require__(7467);
|
||||
const spdx_expression_parse_1 = __importDefault(__nccwpck_require__(1620));
|
||||
const packageurl_js_1 = __nccwpck_require__(8915);
|
||||
function groupDependenciesByManifest(changes) {
|
||||
var _a;
|
||||
const dependencies = new Map();
|
||||
@@ -1519,23 +1665,6 @@ function octokitClient(token = 'repo-token', required = true) {
|
||||
return new octokit_1.Octokit(opts);
|
||||
}
|
||||
exports.octokitClient = octokitClient;
|
||||
const parsePURL = (purlString) => {
|
||||
try {
|
||||
return packageurl_js_1.PackageURL.fromString(purlString);
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message ===
|
||||
`purl is missing the required "name" component.`) {
|
||||
//packageurl-js does not support empty names, so will manually override it for deny-groups
|
||||
//https://github.com/package-url/packageurl-js/blob/master/src/package-url.js#L216
|
||||
const purl = packageurl_js_1.PackageURL.fromString(`${purlString}TEMP_NAME`);
|
||||
purl.name = '';
|
||||
return purl;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
exports.parsePURL = parsePURL;
|
||||
|
||||
|
||||
/***/ }),
|
||||
@@ -5420,11 +5549,11 @@ __export(dist_src_exports, {
|
||||
module.exports = __toCommonJS(dist_src_exports);
|
||||
var import_universal_user_agent = __nccwpck_require__(5030);
|
||||
var import_request = __nccwpck_require__(6234);
|
||||
var import_auth_oauth_app = __nccwpck_require__(8459);
|
||||
var import_auth_oauth_app = __nccwpck_require__(4098);
|
||||
|
||||
// pkg/dist-src/auth.js
|
||||
var import_deprecation = __nccwpck_require__(8932);
|
||||
var OAuthAppAuth = __toESM(__nccwpck_require__(8459));
|
||||
var OAuthAppAuth = __toESM(__nccwpck_require__(4098));
|
||||
|
||||
// pkg/dist-src/get-app-authentication.js
|
||||
var import_universal_github_app_jwt = __nccwpck_require__(4419);
|
||||
@@ -5872,7 +6001,7 @@ function createAppAuth(options) {
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 8459:
|
||||
/***/ 4098:
|
||||
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
@@ -7382,7 +7511,7 @@ __export(dist_src_exports, {
|
||||
unknownRouteResponse: () => unknownRouteResponse
|
||||
});
|
||||
module.exports = __toCommonJS(dist_src_exports);
|
||||
var import_auth_oauth_app = __nccwpck_require__(8459);
|
||||
var import_auth_oauth_app = __nccwpck_require__(4098);
|
||||
|
||||
// pkg/dist-src/version.js
|
||||
var VERSION = "6.0.0";
|
||||
@@ -7470,7 +7599,7 @@ function getWebFlowAuthorizationUrlWithState(state, options) {
|
||||
}
|
||||
|
||||
// pkg/dist-src/methods/create-token.js
|
||||
var OAuthAppAuth = __toESM(__nccwpck_require__(8459));
|
||||
var OAuthAppAuth = __toESM(__nccwpck_require__(4098));
|
||||
async function createTokenWithState(state, options) {
|
||||
const authentication = await state.octokit.auth({
|
||||
type: "oauth-user",
|
||||
@@ -18409,272 +18538,6 @@ function onceStrict (fn) {
|
||||
}
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 8915:
|
||||
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||
|
||||
/*!
|
||||
Copyright (c) the purl authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
const PackageURL = __nccwpck_require__(8749);
|
||||
|
||||
module.exports = {
|
||||
PackageURL
|
||||
};
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 8749:
|
||||
/***/ ((module) => {
|
||||
|
||||
/*!
|
||||
Copyright (c) the purl authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
const KnownQualifierNames = Object.freeze({
|
||||
// known qualifiers as defined here:
|
||||
// https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst#known-qualifiers-keyvalue-pairs
|
||||
RepositoryUrl: 'repository_url',
|
||||
DownloadUrl: 'download_url',
|
||||
VcsUrl: 'vcs_url',
|
||||
FileName: 'file_name',
|
||||
Checksum: 'checksum'
|
||||
});
|
||||
|
||||
class PackageURL {
|
||||
|
||||
static get KnownQualifierNames() {
|
||||
return KnownQualifierNames;
|
||||
}
|
||||
|
||||
constructor(type, namespace, name, version, qualifiers, subpath) {
|
||||
let required = { 'type': type, 'name': name };
|
||||
Object.keys(required).forEach(key => {
|
||||
if (!required[key]) {
|
||||
throw new Error('Invalid purl: "' + key + '" is a required field.');
|
||||
}
|
||||
});
|
||||
|
||||
let strings = { 'type': type, 'namespace': namespace, 'name': name, 'versions': version, 'subpath': subpath };
|
||||
Object.keys(strings).forEach(key => {
|
||||
if (strings[key] && typeof strings[key] === 'string' || !strings[key]) {
|
||||
return;
|
||||
}
|
||||
throw new Error('Invalid purl: "' + key + '" argument must be a string.');
|
||||
});
|
||||
|
||||
if (qualifiers) {
|
||||
if (typeof qualifiers !== 'object') {
|
||||
throw new Error('Invalid purl: "qualifiers" argument must be a dictionary.');
|
||||
}
|
||||
Object.keys(qualifiers).forEach(key => {
|
||||
if (!/^[a-z]+$/i.test(key) && !/[\.-_]/.test(key)) {
|
||||
throw new Error('Invalid purl: qualifier "' + key + '" contains an illegal character.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.namespace = namespace;
|
||||
this.version = version;
|
||||
this.qualifiers = qualifiers;
|
||||
this.subpath = subpath;
|
||||
}
|
||||
|
||||
_handlePyPi() {
|
||||
this.name = this.name.toLowerCase().replace(/_/g, '-');
|
||||
}
|
||||
_handlePub() {
|
||||
this.name = this.name.toLowerCase();
|
||||
if (!/^[a-z0-9_]+$/i.test(this.name)) {
|
||||
throw new Error('Invalid purl: contains an illegal character.');
|
||||
}
|
||||
}
|
||||
|
||||
toString() {
|
||||
var purl = ['pkg:', encodeURIComponent(this.type), '/'];
|
||||
|
||||
if (this.type === 'pypi') {
|
||||
this._handlePyPi();
|
||||
}
|
||||
if (this.type === 'pub') {
|
||||
this._handlePub();
|
||||
}
|
||||
|
||||
if (this.namespace) {
|
||||
purl.push(
|
||||
encodeURIComponent(this.namespace)
|
||||
.replace(/%3A/g, ':')
|
||||
.replace(/%2F/g, '/')
|
||||
);
|
||||
purl.push('/');
|
||||
}
|
||||
|
||||
purl.push(encodeURIComponent(this.name).replace(/%3A/g, ':'));
|
||||
|
||||
if (this.version) {
|
||||
purl.push('@');
|
||||
purl.push(encodeURIComponent(this.version).replace(/%3A/g, ':').replace(/%2B/g,'+'));
|
||||
}
|
||||
|
||||
if (this.qualifiers) {
|
||||
purl.push('?');
|
||||
|
||||
let qualifiers = this.qualifiers;
|
||||
let qualifierString = [];
|
||||
Object.keys(qualifiers).sort().forEach(key => {
|
||||
qualifierString.push(
|
||||
encodeURIComponent(key).replace(/%3A/g, ':')
|
||||
+ '='
|
||||
+ encodeURIComponent(qualifiers[key]).replace(/%2F/g, '/')
|
||||
);
|
||||
});
|
||||
|
||||
purl.push(qualifierString.join('&'));
|
||||
}
|
||||
|
||||
if (this.subpath) {
|
||||
purl.push('#');
|
||||
purl.push(encodeURIComponent(this.subpath)
|
||||
.replace(/%3A/g, ':')
|
||||
.replace(/%2F/g, '/'));
|
||||
}
|
||||
|
||||
return purl.join('');
|
||||
}
|
||||
|
||||
static fromString(purl) {
|
||||
if (!purl || typeof purl !== 'string' || !purl.trim()) {
|
||||
throw new Error('A purl string argument is required.');
|
||||
}
|
||||
|
||||
let scheme = purl.slice(0, purl.indexOf(':'))
|
||||
let remainder = purl.slice(purl.indexOf(':') + 1)
|
||||
if (scheme !== 'pkg') {
|
||||
throw new Error('purl is missing the required "pkg" scheme component.');
|
||||
}
|
||||
// this strip '/, // and /// as possible in :// or :///
|
||||
// from https://gist.github.com/refo/47632c8a547f2d9b6517#file-remove-leading-slash
|
||||
remainder = remainder.trim().replace(/^\/+/g, '');
|
||||
|
||||
let type
|
||||
[type, remainder] = remainder.split('/', 2);
|
||||
if (!type || !remainder) {
|
||||
throw new Error('purl is missing the required "type" component.');
|
||||
}
|
||||
type = decodeURIComponent(type)
|
||||
|
||||
let url = new URL(purl);
|
||||
|
||||
let qualifiers = null;
|
||||
url.searchParams.forEach((value, key) => {
|
||||
if (!qualifiers) {
|
||||
qualifiers = {};
|
||||
}
|
||||
qualifiers[key] = value;
|
||||
});
|
||||
let subpath = url.hash;
|
||||
if (subpath.indexOf('#') === 0) {
|
||||
subpath = subpath.substring(1);
|
||||
}
|
||||
subpath = subpath.length === 0
|
||||
? null
|
||||
: decodeURIComponent(subpath)
|
||||
|
||||
if (url.username !== '' || url.password !== '') {
|
||||
throw new Error('Invalid purl: cannot contain a "user:pass@host:port"');
|
||||
}
|
||||
|
||||
// this strip '/, // and /// as possible in :// or :///
|
||||
// from https://gist.github.com/refo/47632c8a547f2d9b6517#file-remove-leading-slash
|
||||
let path = url.pathname.trim().replace(/^\/+/g, '');
|
||||
|
||||
// version is optional - check for existence
|
||||
let version = null;
|
||||
if (path.includes('@')) {
|
||||
let index = path.indexOf('@');
|
||||
let rawVersion= path.substring(index + 1);
|
||||
version = decodeURIComponent(rawVersion);
|
||||
|
||||
// Convert percent-encoded colons (:) back, to stay in line with the `toString`
|
||||
// implementation of this library.
|
||||
// https://github.com/package-url/packageurl-js/blob/58026c86978c6e356e5e07f29ecfdccbf8829918/src/package-url.js#L98C10-L98C10
|
||||
let versionEncoded = encodeURIComponent(version).replace(/%3A/g, ':').replace(/%2B/g,'+');
|
||||
|
||||
if (rawVersion !== versionEncoded) {
|
||||
throw new Error('Invalid purl: version must be percent-encoded');
|
||||
}
|
||||
|
||||
remainder = path.substring(0, index);
|
||||
} else {
|
||||
remainder = path;
|
||||
}
|
||||
|
||||
// The 'remainder' should now consist of an optional namespace and the name
|
||||
let remaining = remainder.split('/').slice(1);
|
||||
let name = null;
|
||||
let namespace = null;
|
||||
if (remaining.length > 1) {
|
||||
let nameIndex = remaining.length - 1;
|
||||
let namespaceComponents = remaining.slice(0, nameIndex);
|
||||
name = decodeURIComponent(remaining[nameIndex]);
|
||||
namespace = decodeURIComponent(namespaceComponents.join('/'));
|
||||
} else if (remaining.length === 1) {
|
||||
name = decodeURIComponent(remaining[0]);
|
||||
}
|
||||
|
||||
if (name === '') {
|
||||
throw new Error('purl is missing the required "name" component.');
|
||||
}
|
||||
|
||||
return new PackageURL(type, namespace, name, version, qualifiers, subpath);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = PackageURL;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 1867:
|
||||
@@ -19451,7 +19314,7 @@ const { MAX_LENGTH, MAX_SAFE_INTEGER } = __nccwpck_require__(2293)
|
||||
const { safeRe: re, t } = __nccwpck_require__(9523)
|
||||
|
||||
const parseOptions = __nccwpck_require__(785)
|
||||
const { compareIdentifiers } = __nccwpck_require__(2463)
|
||||
const { compareIdentifiers } = __nccwpck_require__(5865)
|
||||
class SemVer {
|
||||
constructor (version, options) {
|
||||
options = parseOptions(options)
|
||||
@@ -19824,7 +19687,7 @@ module.exports = cmp
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 3466:
|
||||
/***/ 5280:
|
||||
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||
|
||||
const SemVer = __nccwpck_require__(9087)
|
||||
@@ -20210,7 +20073,7 @@ module.exports = valid
|
||||
const internalRe = __nccwpck_require__(9523)
|
||||
const constants = __nccwpck_require__(2293)
|
||||
const SemVer = __nccwpck_require__(9087)
|
||||
const identifiers = __nccwpck_require__(2463)
|
||||
const identifiers = __nccwpck_require__(5865)
|
||||
const parse = __nccwpck_require__(5925)
|
||||
const valid = __nccwpck_require__(9601)
|
||||
const clean = __nccwpck_require__(8848)
|
||||
@@ -20233,7 +20096,7 @@ const neq = __nccwpck_require__(6017)
|
||||
const gte = __nccwpck_require__(5930)
|
||||
const lte = __nccwpck_require__(7520)
|
||||
const cmp = __nccwpck_require__(5098)
|
||||
const coerce = __nccwpck_require__(3466)
|
||||
const coerce = __nccwpck_require__(5280)
|
||||
const Comparator = __nccwpck_require__(1532)
|
||||
const Range = __nccwpck_require__(9828)
|
||||
const satisfies = __nccwpck_require__(6055)
|
||||
@@ -20357,7 +20220,7 @@ module.exports = debug
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 2463:
|
||||
/***/ 5865:
|
||||
/***/ ((module) => {
|
||||
|
||||
const numeric = /^[0-9]+$/
|
||||
@@ -49735,7 +49598,7 @@ const core = __importStar(__nccwpck_require__(2186));
|
||||
const z = __importStar(__nccwpck_require__(3301));
|
||||
const schemas_1 = __nccwpck_require__(1129);
|
||||
const utils_1 = __nccwpck_require__(1314);
|
||||
const packageurl_js_1 = __nccwpck_require__(8915);
|
||||
const purl_1 = __nccwpck_require__(4498);
|
||||
function readConfig() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const inlineConfig = readInlineConfig();
|
||||
@@ -49918,7 +49781,7 @@ function validatePURL(allow_dependencies_licenses) {
|
||||
if (allow_dependencies_licenses === undefined) {
|
||||
return;
|
||||
}
|
||||
const invalid_purls = allow_dependencies_licenses.filter(purl => !packageurl_js_1.PackageURL.fromString(purl));
|
||||
const invalid_purls = allow_dependencies_licenses.filter(purl => !(0, purl_1.parsePURL)(purl).error);
|
||||
if (invalid_purls.length > 0) {
|
||||
throw new Error(`Invalid purl(s) in allow-dependencies-licenses: ${invalid_purls}`);
|
||||
}
|
||||
@@ -50008,6 +49871,105 @@ function filterAllowedAdvisories(ghsas, changes) {
|
||||
exports.filterAllowedAdvisories = filterAllowedAdvisories;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 4498:
|
||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.parsePURL = exports.PurlSchema = void 0;
|
||||
const z = __importStar(__nccwpck_require__(3301));
|
||||
// the basic purl type, containing type, namespace, name, and version.
|
||||
// other than type, all fields are nullable. this is for maximum flexibility
|
||||
// at the cost of strict adherence to the package-url spec.
|
||||
exports.PurlSchema = z.object({
|
||||
type: z.string(),
|
||||
namespace: z.string().nullable(),
|
||||
name: z.string().nullable(), // name is nullable for deny-groups
|
||||
version: z.string().nullable(),
|
||||
original: z.string(),
|
||||
error: z.string().nullable()
|
||||
});
|
||||
const PURL_TYPE = /pkg:([a-zA-Z0-9-_]+)\/.*/;
|
||||
function parsePURL(purl) {
|
||||
const result = {
|
||||
type: '',
|
||||
namespace: null,
|
||||
name: null,
|
||||
version: null,
|
||||
original: purl,
|
||||
error: null
|
||||
};
|
||||
if (!purl.startsWith('pkg:')) {
|
||||
result.error = 'package-url must start with "pkg:"';
|
||||
return result;
|
||||
}
|
||||
const type = purl.match(PURL_TYPE);
|
||||
if (!type) {
|
||||
result.error = 'package-url must contain a type';
|
||||
return result;
|
||||
}
|
||||
result.type = type[1];
|
||||
const parts = purl.split('/');
|
||||
// the first 'part' should be 'pkg:ecosystem'
|
||||
if (parts.length < 2 || !parts[1]) {
|
||||
result.error = 'package-url must contain a namespace or name';
|
||||
return result;
|
||||
}
|
||||
let namePlusRest;
|
||||
if (parts.length === 2) {
|
||||
namePlusRest = parts[1];
|
||||
}
|
||||
else {
|
||||
result.namespace = decodeURIComponent(parts[1]);
|
||||
namePlusRest = parts[2];
|
||||
}
|
||||
const name = namePlusRest.match(/([^@#?]+)[@#?]?.*/);
|
||||
if (!result.namespace && !name) {
|
||||
result.error = 'package-url must contain a namespace or name';
|
||||
return result;
|
||||
}
|
||||
if (!name) {
|
||||
// we're done here
|
||||
return result;
|
||||
}
|
||||
result.name = decodeURIComponent(name[1]);
|
||||
const version = namePlusRest.match(/@([^#?]+)[#?]?.*/);
|
||||
if (!version) {
|
||||
return result;
|
||||
}
|
||||
result.version = decodeURIComponent(version[1]);
|
||||
// we don't parse subpath or attributes, so we're done here
|
||||
return result;
|
||||
}
|
||||
exports.parsePURL = parsePURL;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 1129:
|
||||
@@ -50041,12 +50003,47 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.ScorecardSchema = exports.ScorecardApiSchema = exports.ComparisonResponseSchema = exports.ChangesSchema = exports.ConfigurationOptionsSchema = exports.PullRequestSchema = exports.ChangeSchema = exports.SeveritySchema = exports.SCOPES = exports.SEVERITIES = void 0;
|
||||
const z = __importStar(__nccwpck_require__(3301));
|
||||
const utils_1 = __nccwpck_require__(1314);
|
||||
const purl_1 = __nccwpck_require__(4498);
|
||||
exports.SEVERITIES = ['critical', 'high', 'moderate', 'low'];
|
||||
exports.SCOPES = ['unknown', 'runtime', 'development'];
|
||||
exports.SeveritySchema = z.enum(exports.SEVERITIES).default('low');
|
||||
const PackageURL = z.string().transform(purlString => {
|
||||
return (0, utils_1.parsePURL)(purlString);
|
||||
const PackageURL = z
|
||||
.string()
|
||||
.transform(purlString => {
|
||||
return (0, purl_1.parsePURL)(purlString);
|
||||
})
|
||||
.superRefine((purl, context) => {
|
||||
if (purl.error) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Error parsing package-url: ${purl.error}`
|
||||
});
|
||||
}
|
||||
if (!purl.name) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Error parsing package-url: name is required`
|
||||
});
|
||||
}
|
||||
});
|
||||
const PackageURLWithNamespace = z
|
||||
.string()
|
||||
.transform(purlString => {
|
||||
return (0, purl_1.parsePURL)(purlString);
|
||||
})
|
||||
.superRefine((purl, context) => {
|
||||
if (purl.error) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Error parsing purl: ${purl.error}`
|
||||
});
|
||||
}
|
||||
if (purl.namespace === null) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `package-url must have a namespace, and the namespace must be followed by '/'`
|
||||
});
|
||||
}
|
||||
});
|
||||
exports.ChangeSchema = z.object({
|
||||
change_type: z.enum(['added', 'removed']),
|
||||
@@ -50082,7 +50079,7 @@ exports.ConfigurationOptionsSchema = z
|
||||
allow_dependencies_licenses: z.array(z.string()).optional(),
|
||||
allow_ghsas: z.array(z.string()).default([]),
|
||||
deny_packages: z.array(PackageURL).default([]),
|
||||
deny_groups: z.array(PackageURL).default([]),
|
||||
deny_groups: z.array(PackageURLWithNamespace).default([]),
|
||||
license_check: z.boolean().default(true),
|
||||
vulnerability_check: z.boolean().default(true),
|
||||
config_file: z.string().optional(),
|
||||
@@ -50205,11 +50202,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.parsePURL = exports.octokitClient = exports.isSPDXValid = exports.renderUrl = exports.getManifestsSet = exports.groupDependenciesByManifest = void 0;
|
||||
exports.octokitClient = exports.isSPDXValid = exports.renderUrl = exports.getManifestsSet = exports.groupDependenciesByManifest = void 0;
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
const octokit_1 = __nccwpck_require__(7467);
|
||||
const spdx_expression_parse_1 = __importDefault(__nccwpck_require__(1620));
|
||||
const packageurl_js_1 = __nccwpck_require__(8915);
|
||||
function groupDependenciesByManifest(changes) {
|
||||
var _a;
|
||||
const dependencies = new Map();
|
||||
@@ -50269,23 +50265,6 @@ function octokitClient(token = 'repo-token', required = true) {
|
||||
return new octokit_1.Octokit(opts);
|
||||
}
|
||||
exports.octokitClient = octokitClient;
|
||||
const parsePURL = (purlString) => {
|
||||
try {
|
||||
return packageurl_js_1.PackageURL.fromString(purlString);
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message ===
|
||||
`purl is missing the required "name" component.`) {
|
||||
//packageurl-js does not support empty names, so will manually override it for deny-groups
|
||||
//https://github.com/package-url/packageurl-js/blob/master/src/package-url.js#L216
|
||||
const purl = packageurl_js_1.PackageURL.fromString(`${purlString}TEMP_NAME`);
|
||||
purl.name = '';
|
||||
return purl;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
exports.parsePURL = parsePURL;
|
||||
|
||||
|
||||
/***/ }),
|
||||
@@ -53675,13 +53654,13 @@ exports.mapIncludes = mapIncludes;
|
||||
|
||||
|
||||
var Alias = __nccwpck_require__(5639);
|
||||
var Collection = __nccwpck_require__(2240);
|
||||
var Collection = __nccwpck_require__(3466);
|
||||
var identity = __nccwpck_require__(5589);
|
||||
var Pair = __nccwpck_require__(246);
|
||||
var toJS = __nccwpck_require__(979);
|
||||
var toJS = __nccwpck_require__(2463);
|
||||
var Schema = __nccwpck_require__(6831);
|
||||
var stringifyDocument = __nccwpck_require__(5225);
|
||||
var anchors = __nccwpck_require__(2723);
|
||||
var anchors = __nccwpck_require__(8459);
|
||||
var applyReviver = __nccwpck_require__(3412);
|
||||
var createNode = __nccwpck_require__(9652);
|
||||
var directives = __nccwpck_require__(5400);
|
||||
@@ -54012,7 +53991,7 @@ exports.Document = Document;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 2723:
|
||||
/***/ 8459:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
@@ -54607,11 +54586,11 @@ exports.warn = warn;
|
||||
"use strict";
|
||||
|
||||
|
||||
var anchors = __nccwpck_require__(2723);
|
||||
var anchors = __nccwpck_require__(8459);
|
||||
var visit = __nccwpck_require__(6796);
|
||||
var identity = __nccwpck_require__(5589);
|
||||
var Node = __nccwpck_require__(1399);
|
||||
var toJS = __nccwpck_require__(979);
|
||||
var toJS = __nccwpck_require__(2463);
|
||||
|
||||
class Alias extends Node.NodeBase {
|
||||
constructor(source) {
|
||||
@@ -54712,7 +54691,7 @@ exports.Alias = Alias;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 2240:
|
||||
/***/ 3466:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
@@ -54880,7 +54859,7 @@ exports.isEmptyPath = isEmptyPath;
|
||||
|
||||
var applyReviver = __nccwpck_require__(3412);
|
||||
var identity = __nccwpck_require__(5589);
|
||||
var toJS = __nccwpck_require__(979);
|
||||
var toJS = __nccwpck_require__(2463);
|
||||
|
||||
class NodeBase {
|
||||
constructor(type) {
|
||||
@@ -54975,7 +54954,7 @@ exports.createPair = createPair;
|
||||
|
||||
var identity = __nccwpck_require__(5589);
|
||||
var Node = __nccwpck_require__(1399);
|
||||
var toJS = __nccwpck_require__(979);
|
||||
var toJS = __nccwpck_require__(2463);
|
||||
|
||||
const isScalarValue = (value) => !value || (typeof value !== 'function' && typeof value !== 'object');
|
||||
class Scalar extends Node.NodeBase {
|
||||
@@ -55010,7 +54989,7 @@ exports.isScalarValue = isScalarValue;
|
||||
|
||||
var stringifyCollection = __nccwpck_require__(2466);
|
||||
var addPairToJSMap = __nccwpck_require__(4676);
|
||||
var Collection = __nccwpck_require__(2240);
|
||||
var Collection = __nccwpck_require__(3466);
|
||||
var identity = __nccwpck_require__(5589);
|
||||
var Pair = __nccwpck_require__(246);
|
||||
var Scalar = __nccwpck_require__(9338);
|
||||
@@ -55165,10 +55144,10 @@ exports.findPair = findPair;
|
||||
|
||||
var createNode = __nccwpck_require__(9652);
|
||||
var stringifyCollection = __nccwpck_require__(2466);
|
||||
var Collection = __nccwpck_require__(2240);
|
||||
var Collection = __nccwpck_require__(3466);
|
||||
var identity = __nccwpck_require__(5589);
|
||||
var Scalar = __nccwpck_require__(9338);
|
||||
var toJS = __nccwpck_require__(979);
|
||||
var toJS = __nccwpck_require__(2463);
|
||||
|
||||
class YAMLSeq extends Collection.Collection {
|
||||
static get tagName() {
|
||||
@@ -55290,7 +55269,7 @@ var log = __nccwpck_require__(6909);
|
||||
var stringify = __nccwpck_require__(8409);
|
||||
var identity = __nccwpck_require__(5589);
|
||||
var Scalar = __nccwpck_require__(9338);
|
||||
var toJS = __nccwpck_require__(979);
|
||||
var toJS = __nccwpck_require__(2463);
|
||||
|
||||
const MERGE_KEY = '<<';
|
||||
function addPairToJSMap(ctx, map, { key, value }) {
|
||||
@@ -55455,7 +55434,7 @@ exports.isSeq = isSeq;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 979:
|
||||
/***/ 2463:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
@@ -58606,7 +58585,7 @@ exports.intOct = intOct;
|
||||
|
||||
|
||||
var identity = __nccwpck_require__(5589);
|
||||
var toJS = __nccwpck_require__(979);
|
||||
var toJS = __nccwpck_require__(2463);
|
||||
var YAMLMap = __nccwpck_require__(6011);
|
||||
var YAMLSeq = __nccwpck_require__(5161);
|
||||
var pairs = __nccwpck_require__(9841);
|
||||
@@ -59192,7 +59171,7 @@ exports.foldFlowLines = foldFlowLines;
|
||||
"use strict";
|
||||
|
||||
|
||||
var anchors = __nccwpck_require__(2723);
|
||||
var anchors = __nccwpck_require__(8459);
|
||||
var identity = __nccwpck_require__(5589);
|
||||
var stringifyComment = __nccwpck_require__(5182);
|
||||
var stringifyString = __nccwpck_require__(6226);
|
||||
@@ -59327,7 +59306,7 @@ exports.stringify = stringify;
|
||||
"use strict";
|
||||
|
||||
|
||||
var Collection = __nccwpck_require__(2240);
|
||||
var Collection = __nccwpck_require__(3466);
|
||||
var identity = __nccwpck_require__(5589);
|
||||
var stringify = __nccwpck_require__(8409);
|
||||
var stringifyComment = __nccwpck_require__(5182);
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
-22
@@ -1519,28 +1519,6 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
packageurl-js
|
||||
MIT
|
||||
Copyright (c) the purl authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
safe-buffer
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
+2
-2
@@ -280,7 +280,7 @@ With the `deny-packages` option, you can exclude dependencies based on their PUR
|
||||
|
||||
Using the `deny-groups` option you can exclude dependencies by their group name/namespace. You can add multiple values separated by a comma.
|
||||
|
||||
In this example, we are excluding all versions of `pkg:maven/org.apache.logging.log4j:log4j-api` and only `2.23.0` of log4j-core `pkg:maven/org.apache.logging.log4j/log4j-core@2.23.0` from `maven` and all packages in the group `pkg:maven/com.bazaarvoice.maven`
|
||||
In this example, we are excluding all versions of `pkg:maven/org.apache.logging.log4j:log4j-api` and only `2.23.0` of log4j-core `pkg:maven/org.apache.logging.log4j/log4j-core@2.23.0` from `maven` and all packages in the group `pkg:maven/com.bazaarvoice.maven/`
|
||||
|
||||
```yaml
|
||||
name: 'Dependency Review'
|
||||
@@ -300,7 +300,7 @@ jobs:
|
||||
uses: actions/dependency-review-action@v4
|
||||
with:
|
||||
deny-packages: 'pkg:maven/org.apache.logging.log4j/log4j-api,pkg:maven/org.apache.logging.log4j/log4j-core@2.23.0'
|
||||
deny-groups: 'pkg:maven/com.bazaarvoice.jolt'
|
||||
deny-groups: 'pkg:maven/com.bazaarvoice.jolt/'
|
||||
```
|
||||
|
||||
## Waiting for dependency submission jobs to complete
|
||||
|
||||
Generated
+2
-8
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "dependency-review-action",
|
||||
"version": "4.3.0",
|
||||
"version": "4.3.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "dependency-review-action",
|
||||
"version": "4.3.0",
|
||||
"version": "4.3.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.1",
|
||||
@@ -18,7 +18,6 @@
|
||||
"got": "^14.2.0",
|
||||
"jest": "^29.7.0",
|
||||
"octokit": "^3.1.2",
|
||||
"packageurl-js": "^1.2.0",
|
||||
"spdx-expression-parse": "^3.0.1",
|
||||
"spdx-satisfies": "^5.0.1",
|
||||
"ts-jest": "^29.1.2",
|
||||
@@ -6651,11 +6650,6 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/packageurl-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/packageurl-js/-/packageurl-js-1.2.1.tgz",
|
||||
"integrity": "sha512-cZ6/MzuXaoFd16/k0WnwtI298UCaDHe/XlSh85SeOKbGZ1hq0xvNbx3ILyCMyk7uFQxl6scF3Aucj6/EO9NwcA=="
|
||||
},
|
||||
"node_modules/parent-module": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||
|
||||
+1
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dependency-review-action",
|
||||
"version": "4.3.0",
|
||||
"version": "4.3.1",
|
||||
"private": true,
|
||||
"description": "A GitHub Action for Dependency Review",
|
||||
"main": "lib/main.js",
|
||||
@@ -34,7 +34,6 @@
|
||||
"got": "^14.2.0",
|
||||
"jest": "^29.7.0",
|
||||
"octokit": "^3.1.2",
|
||||
"packageurl-js": "^1.2.0",
|
||||
"spdx-expression-parse": "^3.0.1",
|
||||
"spdx-satisfies": "^5.0.1",
|
||||
"ts-jest": "^29.1.2",
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ import * as core from '@actions/core'
|
||||
import * as z from 'zod'
|
||||
import {ConfigurationOptions, ConfigurationOptionsSchema} from './schemas'
|
||||
import {isSPDXValid, octokitClient} from './utils'
|
||||
import {PackageURL} from 'packageurl-js'
|
||||
import {parsePURL} from './purl'
|
||||
|
||||
type ConfigurationOptionsPartial = Partial<ConfigurationOptions>
|
||||
|
||||
@@ -233,7 +233,7 @@ function validatePURL(allow_dependencies_licenses: string[] | undefined): void {
|
||||
return
|
||||
}
|
||||
const invalid_purls = allow_dependencies_licenses.filter(
|
||||
purl => !PackageURL.fromString(purl)
|
||||
purl => !parsePURL(purl).error
|
||||
)
|
||||
|
||||
if (invalid_purls.length > 0) {
|
||||
|
||||
+21
-9
@@ -1,6 +1,6 @@
|
||||
import * as core from '@actions/core'
|
||||
import {Change} from './schemas'
|
||||
import {PackageURL} from 'packageurl-js'
|
||||
import {PackageURL, parsePURL} from './purl'
|
||||
|
||||
export async function getDeniedChanges(
|
||||
changes: Change[],
|
||||
@@ -11,12 +11,10 @@ export async function getDeniedChanges(
|
||||
|
||||
let hasDeniedPackage = false
|
||||
for (const change of changes) {
|
||||
const changedPackage = PackageURL.fromString(change.package_url)
|
||||
|
||||
for (const denied of deniedPackages) {
|
||||
if (
|
||||
(!denied.version || changedPackage.version === denied.version) &&
|
||||
changedPackage.name === denied.name
|
||||
(!denied.version || change.version === denied.version) &&
|
||||
change.name === denied.name
|
||||
) {
|
||||
changesDenied.push(change)
|
||||
hasDeniedPackage = true
|
||||
@@ -24,10 +22,13 @@ export async function getDeniedChanges(
|
||||
}
|
||||
|
||||
for (const denied of deniedGroups) {
|
||||
if (
|
||||
changedPackage.namespace &&
|
||||
changedPackage.namespace === denied.namespace
|
||||
) {
|
||||
const namespace = getNamespace(change)
|
||||
if (!denied.namespace) {
|
||||
core.error(
|
||||
`Denied group represented by '${denied.original}' does not have a namespace. The format should be 'pkg:<type>/<namespace>/'.`
|
||||
)
|
||||
}
|
||||
if (namespace && namespace === denied.namespace) {
|
||||
changesDenied.push(change)
|
||||
hasDeniedPackage = true
|
||||
}
|
||||
@@ -42,3 +43,14 @@ export async function getDeniedChanges(
|
||||
|
||||
return changesDenied
|
||||
}
|
||||
|
||||
export const getNamespace = (change: Change): string | null => {
|
||||
if (change.package_url) {
|
||||
return parsePURL(change.package_url).namespace
|
||||
}
|
||||
const matches = change.name.match(/([^:/]+)[:/]/)
|
||||
if (matches && matches.length > 1) {
|
||||
return matches[1]
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
+3
-5
@@ -1,7 +1,7 @@
|
||||
import spdxSatisfies from 'spdx-satisfies'
|
||||
import {Change, Changes} from './schemas'
|
||||
import {isSPDXValid, octokitClient} from './utils'
|
||||
import {PackageURL} from 'packageurl-js'
|
||||
import {parsePURL} from './purl'
|
||||
|
||||
/**
|
||||
* Loops through a list of changes, filtering and returning the
|
||||
@@ -32,7 +32,7 @@ export async function getInvalidLicenseChanges(
|
||||
const {allow, deny} = licenses
|
||||
const licenseExclusions = licenses.licenseExclusions?.map(
|
||||
(pkgUrl: string) => {
|
||||
return PackageURL.fromString(encodeURI(pkgUrl))
|
||||
return parsePURL(pkgUrl)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -45,9 +45,7 @@ export async function getInvalidLicenseChanges(
|
||||
return true
|
||||
}
|
||||
|
||||
const changeAsPackageURL = PackageURL.fromString(
|
||||
encodeURI(change.package_url)
|
||||
)
|
||||
const changeAsPackageURL = parsePURL(encodeURI(change.package_url))
|
||||
|
||||
// We want to find if the licenseExclussion list contains the PackageURL of the Change
|
||||
// If it does, we want to filter it out and therefore return false
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
import * as z from 'zod'
|
||||
|
||||
// the basic purl type, containing type, namespace, name, and version.
|
||||
// other than type, all fields are nullable. this is for maximum flexibility
|
||||
// at the cost of strict adherence to the package-url spec.
|
||||
export const PurlSchema = z.object({
|
||||
type: z.string(),
|
||||
namespace: z.string().nullable(),
|
||||
name: z.string().nullable(), // name is nullable for deny-groups
|
||||
version: z.string().nullable(),
|
||||
original: z.string(),
|
||||
error: z.string().nullable()
|
||||
})
|
||||
|
||||
export type PackageURL = z.infer<typeof PurlSchema>
|
||||
|
||||
const PURL_TYPE = /pkg:([a-zA-Z0-9-_]+)\/.*/
|
||||
|
||||
export function parsePURL(purl: string): PackageURL {
|
||||
const result: PackageURL = {
|
||||
type: '',
|
||||
namespace: null,
|
||||
name: null,
|
||||
version: null,
|
||||
original: purl,
|
||||
error: null
|
||||
}
|
||||
if (!purl.startsWith('pkg:')) {
|
||||
result.error = 'package-url must start with "pkg:"'
|
||||
return result
|
||||
}
|
||||
const type = purl.match(PURL_TYPE)
|
||||
if (!type) {
|
||||
result.error = 'package-url must contain a type'
|
||||
return result
|
||||
}
|
||||
result.type = type[1]
|
||||
const parts = purl.split('/')
|
||||
// the first 'part' should be 'pkg:ecosystem'
|
||||
if (parts.length < 2 || !parts[1]) {
|
||||
result.error = 'package-url must contain a namespace or name'
|
||||
return result
|
||||
}
|
||||
let namePlusRest: string
|
||||
if (parts.length === 2) {
|
||||
namePlusRest = parts[1]
|
||||
} else {
|
||||
result.namespace = decodeURIComponent(parts[1])
|
||||
namePlusRest = parts[2]
|
||||
}
|
||||
const name = namePlusRest.match(/([^@#?]+)[@#?]?.*/)
|
||||
if (!result.namespace && !name) {
|
||||
result.error = 'package-url must contain a namespace or name'
|
||||
return result
|
||||
}
|
||||
if (!name) {
|
||||
// we're done here
|
||||
return result
|
||||
}
|
||||
result.name = decodeURIComponent(name[1])
|
||||
const version = namePlusRest.match(/@([^#?]+)[#?]?.*/)
|
||||
if (!version) {
|
||||
return result
|
||||
}
|
||||
result.version = decodeURIComponent(version[1])
|
||||
|
||||
// we don't parse subpath or attributes, so we're done here
|
||||
return result
|
||||
}
|
||||
+41
-5
@@ -1,14 +1,50 @@
|
||||
import * as z from 'zod'
|
||||
import {parsePURL} from './utils'
|
||||
import {parsePURL} from './purl'
|
||||
|
||||
export const SEVERITIES = ['critical', 'high', 'moderate', 'low'] as const
|
||||
export const SCOPES = ['unknown', 'runtime', 'development'] as const
|
||||
|
||||
export const SeveritySchema = z.enum(SEVERITIES).default('low')
|
||||
|
||||
const PackageURL = z.string().transform(purlString => {
|
||||
return parsePURL(purlString)
|
||||
})
|
||||
const PackageURL = z
|
||||
.string()
|
||||
.transform(purlString => {
|
||||
return parsePURL(purlString)
|
||||
})
|
||||
.superRefine((purl, context) => {
|
||||
if (purl.error) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Error parsing package-url: ${purl.error}`
|
||||
})
|
||||
}
|
||||
if (!purl.name) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Error parsing package-url: name is required`
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const PackageURLWithNamespace = z
|
||||
.string()
|
||||
.transform(purlString => {
|
||||
return parsePURL(purlString)
|
||||
})
|
||||
.superRefine((purl, context) => {
|
||||
if (purl.error) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Error parsing purl: ${purl.error}`
|
||||
})
|
||||
}
|
||||
if (purl.namespace === null) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `package-url must have a namespace, and the namespace must be followed by '/'`
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
export const ChangeSchema = z.object({
|
||||
change_type: z.enum(['added', 'removed']),
|
||||
@@ -48,7 +84,7 @@ export const ConfigurationOptionsSchema = z
|
||||
allow_dependencies_licenses: z.array(z.string()).optional(),
|
||||
allow_ghsas: z.array(z.string()).default([]),
|
||||
deny_packages: z.array(PackageURL).default([]),
|
||||
deny_groups: z.array(PackageURL).default([]),
|
||||
deny_groups: z.array(PackageURLWithNamespace).default([]),
|
||||
license_check: z.boolean().default(true),
|
||||
vulnerability_check: z.boolean().default(true),
|
||||
config_file: z.string().optional(),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import * as core from '@actions/core'
|
||||
import {Octokit} from 'octokit'
|
||||
import spdxParse from 'spdx-expression-parse'
|
||||
import {PackageURL} from 'packageurl-js'
|
||||
import {Changes} from './schemas'
|
||||
|
||||
export function groupDependenciesByManifest(
|
||||
@@ -69,21 +68,3 @@ export function octokitClient(token = 'repo-token', required = true): Octokit {
|
||||
|
||||
return new Octokit(opts)
|
||||
}
|
||||
|
||||
export const parsePURL = (purlString: string): PackageURL => {
|
||||
try {
|
||||
return PackageURL.fromString(purlString)
|
||||
} catch (error) {
|
||||
if (
|
||||
(error as Error).message ===
|
||||
`purl is missing the required "name" component.`
|
||||
) {
|
||||
//packageurl-js does not support empty names, so will manually override it for deny-groups
|
||||
//https://github.com/package-url/packageurl-js/blob/master/src/package-url.js#L216
|
||||
const purl = PackageURL.fromString(`${purlString}TEMP_NAME`)
|
||||
purl.name = ''
|
||||
return purl
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user