Compare commits

..
14 changed files with 282 additions and 789 deletions
@@ -1,7 +0,0 @@
## Purpose
_Describe the purpose of this pull request_
## Related Issues
_What issues does this PR close or relate to?_
+1 -1
View File
@@ -16,7 +16,7 @@ If you've encountered a problem, please let us know by [submitting an issue](htt
## Enhancements and feature requests ## Enhancements and feature requests
If you've got an idea for a new feature or a significant change to the code or its dependencies, please submit as [an issue](https://github.com/actions/dependency-review-action/issues/new) so that the community can see it, and we can discuss it there. We may not be able to respond to every single issue, but will make a best effort! If you've got an idea for a new feature, please submit as [an issue](https://github.com/actions/dependency-review-action/issues/new) so that the community can see it, and we can discuss it there. We may not be able to respond to every single issue, but will make a best effort!
If you'd like to make a contribution yourself, we ask that before significant effort is put into code changes, that we have agreement that the change aligns with our strategy for the action. Since this is a verified Action owned by GitHub we want to make sure that contributions are high quality, and that they maintain consistency with the rest of the action's behavior. If you'd like to make a contribution yourself, we ask that before significant effort is put into code changes, that we have agreement that the change aligns with our strategy for the action. Since this is a verified Action owned by GitHub we want to make sure that contributions are high quality, and that they maintain consistency with the rest of the action's behavior.
-45
View File
@@ -124,51 +124,6 @@ test('it raises an error when no refs are provided and the event is not a pull r
).toThrow() ).toThrow()
}) })
const pullRequestLikeEvents = [
'pull_request',
'pull_request_target',
'merge_group'
]
test.each(pullRequestLikeEvents)(
'it uses the given refs even when the event is %s',
async eventName => {
setInput('base-ref', 'a-custom-base-ref')
setInput('head-ref', 'a-custom-head-ref')
const refs = getRefs(await readConfig(), {
payload: {
pull_request: {
number: 42,
base: {sha: 'pr-base-ref'},
head: {sha: 'pr-head-ref'}
}
},
eventName
})
expect(refs.base).toEqual('a-custom-base-ref')
expect(refs.head).toEqual('a-custom-head-ref')
}
)
test.each(pullRequestLikeEvents)(
'it uses the event refs when the event is %s and the no refs are input',
async eventName => {
const refs = getRefs(await readConfig(), {
payload: {
pull_request: {
number: 42,
base: {sha: 'pr-base-ref'},
head: {sha: 'pr-head-ref'}
}
},
eventName
})
expect(refs.base).toEqual('pr-base-ref')
expect(refs.head).toEqual('pr-head-ref')
}
)
test('it defaults to runtime scope', async () => { test('it defaults to runtime scope', async () => {
const config = await readConfig() const config = await readConfig()
expect(config.fail_on_scopes).toEqual(['runtime']) expect(config.fail_on_scopes).toEqual(['runtime'])
+31 -21
View File
@@ -1,7 +1,7 @@
import {expect, test, describe} from '@jest/globals' import {expect, test} from '@jest/globals'
import * as spdx from '../src/spdx' import * as spdx from '../src/spdx'
describe('satisfiesAny', () => { test('satisfiesAny', () => {
const units = [ const units = [
{ {
candidate: 'MIT', candidate: 'MIT',
@@ -59,14 +59,17 @@ describe('satisfiesAny', () => {
] ]
for (const unit of units) { for (const unit of units) {
const got: boolean = spdx.satisfiesAny(unit.candidate, unit.licenses) let got: boolean = spdx.satisfiesAny(unit.candidate, unit.licenses)
test(`should return ${unit.expected} for ("${unit.candidate}", "${unit.licenses}")`, () => { if (got != unit.expected) {
expect(got).toBe(unit.expected) console.log(
}) `failing unit test inputs: candidate(${unit.candidate}) licenses(${unit.licenses})`
)
}
expect(got).toBe(unit.expected)
} }
}) })
describe('satisfiesAll', () => { test('satisfiesAll', () => {
const units = [ const units = [
{ {
candidate: 'MIT', candidate: 'MIT',
@@ -134,14 +137,17 @@ describe('satisfiesAll', () => {
] ]
for (const unit of units) { for (const unit of units) {
const got: boolean = spdx.satisfiesAll(unit.candidate, unit.licenses) let got: boolean = spdx.satisfiesAll(unit.candidate, unit.licenses)
test(`should return ${unit.expected} for ("${unit.candidate}", "${unit.licenses}")`, () => { if (got != unit.expected) {
expect(got).toBe(unit.expected) console.log(
}) `failing unit test inputs: candidate(${unit.candidate}) licenses(${unit.licenses})`
)
}
expect(got).toBe(unit.expected)
} }
}) })
describe('satisfies', () => { test('satisfies', () => {
const units = [ const units = [
{ {
candidate: 'MIT', candidate: 'MIT',
@@ -214,14 +220,17 @@ describe('satisfies', () => {
] ]
for (const unit of units) { for (const unit of units) {
const got: boolean = spdx.satisfies(unit.candidate, unit.constraint) let got: boolean = spdx.satisfies(unit.candidate, unit.constraint)
test(`should return ${unit.expected} for ("${unit.candidate}", "${unit.constraint}")`, () => { if (got != unit.expected) {
expect(got).toBe(unit.expected) console.log(
}) `failing unit test inputs: candidateExpr(${unit.candidate}) constraintExpr(${unit.constraint})`
)
}
expect(got).toBe(unit.expected)
} }
}) })
describe('isValid', () => { test('isValid', () => {
const units = [ const units = [
{ {
candidate: 'MIT', candidate: 'MIT',
@@ -249,9 +258,10 @@ describe('isValid', () => {
} }
] ]
for (const unit of units) { for (const unit of units) {
const got: boolean = spdx.isValid(unit.candidate) let got: boolean = spdx.isValid(unit.candidate)
test(`should return ${unit.expected} for ("${unit.candidate}")`, () => { if (got != unit.expected) {
expect(got).toBe(unit.expected) console.log(`failing unit test inputs: candidateExpr(${unit.candidate})`)
}) }
expect(got).toBe(unit.expected)
} }
}) })
+43 -3
View File
@@ -109,6 +109,42 @@ test('prints headline as h1', () => {
expect(text).toContain('<h1>Dependency Review</h1>') expect(text).toContain('<h1>Dependency Review</h1>')
}) })
test('returns minimal summary in case the core.summary is too large for a PR comment', () => {
let changes: Changes = [
createTestChange({name: 'lodash', version: '1.2.3'}),
createTestChange({name: 'colors', version: '2.3.4'}),
createTestChange({name: '@foo/bar', version: '*'})
]
let minSummary: string = summary.addSummaryToSummary(
changes,
emptyInvalidLicenseChanges,
emptyChanges,
scorecard,
defaultConfig
)
// side effect DR report into core.summary as happens in main.ts
summary.addScannedDependencies(changes)
const text = core.summary.stringify()
expect(text).toContain('<h1>Dependency Review</h1>')
expect(minSummary).toContain('# Dependency Review')
expect(text).toContain('❌ 3 vulnerable package(s)')
expect(text).not.toContain('* ❌ 3 vulnerable package(s)')
expect(text).toContain('lodash')
expect(text).toContain('colors')
expect(text).toContain('@foo/bar')
expect(minSummary).toContain('* ❌ 3 vulnerable package(s)')
expect(minSummary).not.toContain('lodash')
expect(minSummary).not.toContain('colors')
expect(minSummary).not.toContain('@foo/bar')
expect(text.length).toBeGreaterThan(minSummary.length)
})
test('returns minimal summary formatted for posting as a PR comment', () => { test('returns minimal summary formatted for posting as a PR comment', () => {
const OLD_ENV = process.env const OLD_ENV = process.env
@@ -196,10 +232,14 @@ test('groups dependencies with empty manifest paths together', () => {
emptyScorecard, emptyScorecard,
defaultConfig defaultConfig
) )
summary.addScannedFiles(changesWithEmptyManifests) summary.addScannedDependencies(changesWithEmptyManifests)
const text = core.summary.stringify() const text = core.summary.stringify()
expect(text).toContain('Unnamed Manifest')
expect(text).toContain('python/dist-info/METADATA') expect(text).toContain('<summary>Unnamed Manifest</summary>')
expect(text).toContain('castore')
expect(text).toContain('connection')
expect(text).toContain('<summary>python/dist-info/METADATA</summary>')
expect(text).toContain('pygments')
}) })
test('does not include status section if nothing was found', () => { test('does not include status section if nothing was found', () => {
Generated Vendored
+133 -568
View File
File diff suppressed because it is too large Load Diff
Generated Vendored
+1 -1
View File
File diff suppressed because one or more lines are too long
+48 -92
View File
@@ -1,12 +1,12 @@
{ {
"name": "dependency-review-action", "name": "dependency-review-action",
"version": "4.3.4", "version": "4.3.3",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "dependency-review-action", "name": "dependency-review-action",
"version": "4.3.4", "version": "4.3.3",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/core": "^1.10.1", "@actions/core": "^1.10.1",
@@ -15,14 +15,14 @@
"@octokit/request-error": "^5.0.1", "@octokit/request-error": "^5.0.1",
"@onebeyond/spdx-license-satisfies": "^1.0.1", "@onebeyond/spdx-license-satisfies": "^1.0.1",
"ansi-styles": "^6.2.1", "ansi-styles": "^6.2.1",
"got": "^14.4.1", "got": "^14.2.0",
"jest": "^29.7.0", "jest": "^29.7.0",
"octokit": "^3.1.2", "octokit": "^3.1.2",
"spdx-expression-parse": "^3.0.1", "spdx-expression-parse": "^3.0.1",
"spdx-satisfies": "^5.0.1", "spdx-satisfies": "^5.0.1",
"ts-jest": "^29.1.2", "ts-jest": "^29.1.2",
"yaml": "^2.3.4", "yaml": "^2.3.4",
"zod": "^3.23.8" "zod": "^3.22.3"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
@@ -1945,20 +1945,15 @@
"url": "https://opencollective.com/unts" "url": "https://opencollective.com/unts"
} }
}, },
"node_modules/@sec-ant/readable-stream": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz",
"integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="
},
"node_modules/@sinclair/typebox": { "node_modules/@sinclair/typebox": {
"version": "0.27.8", "version": "0.27.8",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
"integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="
}, },
"node_modules/@sindresorhus/is": { "node_modules/@sindresorhus/is": {
"version": "6.3.1", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-6.3.1.tgz", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-6.1.0.tgz",
"integrity": "sha512-FX4MfcifwJyFOI2lPoX7PQxCqx8BG1HCho7WdiXwpEQx1Ycij0JxkfYtGK7yqNScrZGSlt6RE6sw8QYoH7eKnQ==", "integrity": "sha512-BuvU07zq3tQ/2SIgBsEuxKYDyDjC0n7Zir52bpHy2xnBbW81+po43aLFPLbeV3HRAheFbGud1qgcqSYfhtHMAg==",
"engines": { "engines": {
"node": ">=16" "node": ">=16"
}, },
@@ -2105,11 +2100,11 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "20.16.0", "version": "20.11.28",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.0.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.28.tgz",
"integrity": "sha512-vDxceJcoZhIVh67S568bm1UGZO0DX0hpplJZxzeXMKwIPLn190ec5RRxQ69BKhX44SUGIxxgMdDY557lGLKprQ==", "integrity": "sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==",
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~5.26.4"
} }
}, },
"node_modules/@types/semver": { "node_modules/@types/semver": {
@@ -2816,11 +2811,11 @@
} }
}, },
"node_modules/braces": { "node_modules/braces": {
"version": "3.0.3", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dependencies": { "dependencies": {
"fill-range": "^7.1.1" "fill-range": "^7.0.1"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
@@ -2900,46 +2895,20 @@
} }
}, },
"node_modules/cacheable-request": { "node_modules/cacheable-request": {
"version": "12.0.1", "version": "10.2.14",
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-12.0.1.tgz", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz",
"integrity": "sha512-Yo9wGIQUaAfIbk+qY0X4cDQgCosecfBe3V9NSyeY4qPC2SAkbCS4Xj79VP8WOzitpJUZKc/wsRCYF5ariDIwkg==", "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==",
"dependencies": { "dependencies": {
"@types/http-cache-semantics": "^4.0.4", "@types/http-cache-semantics": "^4.0.2",
"get-stream": "^9.0.1", "get-stream": "^6.0.1",
"http-cache-semantics": "^4.1.1", "http-cache-semantics": "^4.1.1",
"keyv": "^4.5.4", "keyv": "^4.5.3",
"mimic-response": "^4.0.0", "mimic-response": "^4.0.0",
"normalize-url": "^8.0.1", "normalize-url": "^8.0.0",
"responselike": "^3.0.0" "responselike": "^3.0.0"
}, },
"engines": { "engines": {
"node": ">=18" "node": ">=14.16"
}
},
"node_modules/cacheable-request/node_modules/get-stream": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz",
"integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==",
"dependencies": {
"@sec-ant/readable-stream": "^0.4.1",
"is-stream": "^4.0.1"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/cacheable-request/node_modules/is-stream": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz",
"integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/call-bind": { "node_modules/call-bind": {
@@ -4516,9 +4485,9 @@
} }
}, },
"node_modules/fill-range": { "node_modules/fill-range": {
"version": "7.1.1", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dependencies": { "dependencies": {
"to-regex-range": "^5.0.1" "to-regex-range": "^5.0.1"
}, },
@@ -4792,22 +4761,21 @@
} }
}, },
"node_modules/got": { "node_modules/got": {
"version": "14.4.1", "version": "14.2.0",
"resolved": "https://registry.npmjs.org/got/-/got-14.4.1.tgz", "resolved": "https://registry.npmjs.org/got/-/got-14.2.0.tgz",
"integrity": "sha512-IvDJbJBUeexX74xNQuMIVgCRRuNOm5wuK+OC3Dc2pnSoh1AOmgc7JVj7WC+cJ4u0aPcO9KZ2frTXcqK4W/5qTQ==", "integrity": "sha512-dBq2KkHcQl3AwPoIWsLsQScCPpUgRulz1qZVthjPYKYOPmYfBnekR3vxecjZbm91Vc3JUGnV9mqFX7B+Fe2quw==",
"dependencies": { "dependencies": {
"@sindresorhus/is": "^6.3.1", "@sindresorhus/is": "^6.1.0",
"@szmarczak/http-timer": "^5.0.1", "@szmarczak/http-timer": "^5.0.1",
"cacheable-lookup": "^7.0.0", "cacheable-lookup": "^7.0.0",
"cacheable-request": "^12.0.1", "cacheable-request": "^10.2.14",
"decompress-response": "^6.0.0", "decompress-response": "^6.0.0",
"form-data-encoder": "^4.0.2", "form-data-encoder": "^4.0.2",
"get-stream": "^8.0.1", "get-stream": "^8.0.1",
"http2-wrapper": "^2.2.1", "http2-wrapper": "^2.2.1",
"lowercase-keys": "^3.0.0", "lowercase-keys": "^3.0.0",
"p-cancelable": "^4.0.1", "p-cancelable": "^4.0.1",
"responselike": "^3.0.0", "responselike": "^3.0.0"
"type-fest": "^4.19.0"
}, },
"engines": { "engines": {
"node": ">=20" "node": ">=20"
@@ -4827,17 +4795,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/got/node_modules/type-fest": {
"version": "4.20.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.20.0.tgz",
"integrity": "sha512-MBh+PHUHHisjXf4tlx0CFWoMdjx8zCMLJHOjnV1prABYZFHqtFOyauCIK2/7w4oIfwkF8iNhLtnJEfVY2vn3iw==",
"engines": {
"node": ">=16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/graceful-fs": { "node_modules/graceful-fs": {
"version": "4.2.11", "version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -6341,12 +6298,11 @@
} }
}, },
"node_modules/micromatch": { "node_modules/micromatch": {
"version": "4.0.8", "version": "4.0.5",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
"license": "MIT",
"dependencies": { "dependencies": {
"braces": "^3.0.3", "braces": "^3.0.2",
"picomatch": "^2.3.1" "picomatch": "^2.3.1"
}, },
"engines": { "engines": {
@@ -6485,9 +6441,9 @@
} }
}, },
"node_modules/normalize-url": { "node_modules/normalize-url": {
"version": "8.0.1", "version": "8.0.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz",
"integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==",
"engines": { "engines": {
"node": ">=14.16" "node": ">=14.16"
}, },
@@ -7903,9 +7859,9 @@
"dev": true "dev": true
}, },
"node_modules/undici": { "node_modules/undici": {
"version": "5.28.4", "version": "5.28.3",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz",
"integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", "integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==",
"dependencies": { "dependencies": {
"@fastify/busboy": "^2.0.0" "@fastify/busboy": "^2.0.0"
}, },
@@ -7914,9 +7870,9 @@
} }
}, },
"node_modules/undici-types": { "node_modules/undici-types": {
"version": "6.19.6", "version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.6.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org==" "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
}, },
"node_modules/universal-github-app-jwt": { "node_modules/universal-github-app-jwt": {
"version": "1.1.2", "version": "1.1.2",
@@ -8210,9 +8166,9 @@
} }
}, },
"node_modules/zod": { "node_modules/zod": {
"version": "3.23.8", "version": "3.22.4",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz",
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==",
"funding": { "funding": {
"url": "https://github.com/sponsors/colinhacks" "url": "https://github.com/sponsors/colinhacks"
} }
+3 -3
View File
@@ -1,6 +1,6 @@
{ {
"name": "dependency-review-action", "name": "dependency-review-action",
"version": "4.3.4", "version": "4.3.3",
"private": true, "private": true,
"description": "A GitHub Action for Dependency Review", "description": "A GitHub Action for Dependency Review",
"main": "lib/main.js", "main": "lib/main.js",
@@ -31,14 +31,14 @@
"@octokit/request-error": "^5.0.1", "@octokit/request-error": "^5.0.1",
"@onebeyond/spdx-license-satisfies": "^1.0.1", "@onebeyond/spdx-license-satisfies": "^1.0.1",
"ansi-styles": "^6.2.1", "ansi-styles": "^6.2.1",
"got": "^14.4.1", "got": "^14.2.0",
"jest": "^29.7.0", "jest": "^29.7.0",
"octokit": "^3.1.2", "octokit": "^3.1.2",
"spdx-expression-parse": "^3.0.1", "spdx-expression-parse": "^3.0.1",
"spdx-satisfies": "^5.0.1", "spdx-satisfies": "^5.0.1",
"ts-jest": "^29.1.2", "ts-jest": "^29.1.2",
"yaml": "^2.3.4", "yaml": "^2.3.4",
"zod": "^3.23.8" "zod": "^3.22.3"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
+1 -1
View File
@@ -143,7 +143,7 @@ async function createSummary(
...licenseIssues.unlicensed ...licenseIssues.unlicensed
] ]
summary.addScannedFiles(allChanges) summary.addScannedDependencies(allChanges)
const text = core.summary.stringify() const text = core.summary.stringify()
await fs.promises.writeFile(path.resolve(tmpDir, fileName), text, { await fs.promises.writeFile(path.resolve(tmpDir, fileName), text, {
+4 -5
View File
@@ -11,8 +11,7 @@ export function getRefs(
// The base/head ref from the config take priority, if provided. // The base/head ref from the config take priority, if provided.
if ( if (
context.eventName === 'pull_request' || context.eventName === 'pull_request' ||
context.eventName === 'pull_request_target' || context.eventName === 'pull_request_target'
context.eventName === 'merge_group'
) { ) {
const pull_request = PullRequestSchema.parse(context.payload.pull_request) const pull_request = PullRequestSchema.parse(context.payload.pull_request)
base_ref = base_ref || pull_request.base.sha base_ref = base_ref || pull_request.base.sha
@@ -23,19 +22,19 @@ export function getRefs(
throw new Error( throw new Error(
'Both a base ref and head ref must be provided, either via the `base_ref`/`head_ref` ' + 'Both a base ref and head ref must be provided, either via the `base_ref`/`head_ref` ' +
'config options, `base-ref`/`head-ref` workflow action options, or by running a ' + 'config options, `base-ref`/`head-ref` workflow action options, or by running a ' +
'`pull_request`/`pull_request_target`/`merge_group` workflow.' '`pull_request`/`pull_request_target` workflow.'
) )
} else if (!base_ref) { } else if (!base_ref) {
throw new Error( throw new Error(
'A base ref must be provided, either via the `base_ref` config option, ' + 'A base ref must be provided, either via the `base_ref` config option, ' +
'`base-ref` workflow action option, or by running a ' + '`base-ref` workflow action option, or by running a ' +
'`pull_request`/`pull_request_target`/`merge_group` workflow.' '`pull_request`/`pull_request_target` workflow.'
) )
} else if (!head_ref) { } else if (!head_ref) {
throw new Error( throw new Error(
'A head ref must be provided, either via the `head_ref` config option, ' + 'A head ref must be provided, either via the `head_ref` config option, ' +
'`head-ref` workflow action option, or by running a ' + '`head-ref` workflow action option, or by running a ' +
'or by running a `pull_request`/`pull_request_target`/`merge_group` workflow.' 'or by running a `pull_request`/`pull_request_target` workflow.'
) )
} }
+3 -16
View File
@@ -125,9 +125,7 @@ async function run(): Promise<void> {
config.deny_groups config.deny_groups
) )
// generate informational scorecard entries for all added changes in the PR const scorecard = await getScorecardLevels(filteredChanges)
const scorecardChanges = getScorecardChanges(changes)
const scorecard = await getScorecardLevels(scorecardChanges)
const minSummary = summary.addSummaryToSummary( const minSummary = summary.addSummaryToSummary(
vulnerableChanges, vulnerableChanges,
@@ -166,7 +164,7 @@ async function run(): Promise<void> {
} }
core.setOutput('dependency-changes', JSON.stringify(changes)) core.setOutput('dependency-changes', JSON.stringify(changes))
summary.addScannedFiles(changes) summary.addScannedDependencies(changes)
printScannedDependencies(changes) printScannedDependencies(changes)
// include full summary in output; Actions will truncate if oversized // include full summary in output; Actions will truncate if oversized
@@ -371,7 +369,7 @@ function printScannedDependencies(changes: Changes): void {
} }
function printDeniedDependencies( function printDeniedDependencies(
changes: Changes, changes: Change[],
config: ConfigurationOptions config: ConfigurationOptions
): void { ): void {
core.group('Denied', async () => { core.group('Denied', async () => {
@@ -386,17 +384,6 @@ function printDeniedDependencies(
}) })
} }
function getScorecardChanges(changes: Changes): Changes {
const out: Changes = []
for (const change of changes) {
if (change.change_type === 'added') {
out.push(change)
}
}
return out
}
async function createScorecardWarnings( async function createScorecardWarnings(
scorecards: Scorecard, scorecards: Scorecard,
config: ConfigurationOptions config: ConfigurationOptions
+12 -26
View File
@@ -1,7 +1,7 @@
import * as core from '@actions/core' import * as core from '@actions/core'
import {ConfigurationOptions, Changes, Change, Scorecard} from './schemas'
import {SummaryTableRow} from '@actions/core/lib/summary' import {SummaryTableRow} from '@actions/core/lib/summary'
import {InvalidLicenseChanges, InvalidLicenseChangeTypes} from './licenses' import {InvalidLicenseChanges, InvalidLicenseChangeTypes} from './licenses'
import {Change, Changes, ConfigurationOptions, Scorecard} from './schemas'
import {groupDependenciesByManifest, getManifestsSet, renderUrl} from './utils' import {groupDependenciesByManifest, getManifestsSet, renderUrl} from './utils'
const icons = { const icons = {
@@ -10,8 +10,6 @@ const icons = {
warning: '⚠️' warning: '⚠️'
} }
const MAX_SCANNED_FILES_BYTES = 1048576
// generates the DR report summmary and caches it to the Action's core.summary. // generates the DR report summmary and caches it to the Action's core.summary.
// returns the DR summary string, ready to be posted as a PR comment if the // returns the DR summary string, ready to be posted as a PR comment if the
// final DR report is too large // final DR report is too large
@@ -265,33 +263,21 @@ function formatLicense(license: string | null): string {
return license return license
} }
export function addScannedFiles(changes: Changes): void { export function addScannedDependencies(changes: Changes): void {
const manifests = Array.from( const dependencies = groupDependenciesByManifest(changes)
groupDependenciesByManifest(changes).keys() const manifests = dependencies.keys()
).sort()
let sf_size = 0 const summary = core.summary.addHeading('Scanned Manifest Files', 2)
let trunc_at = -1
for (const [index, entry] of manifests.entries()) { for (const manifest of manifests) {
if (sf_size + entry.length >= MAX_SCANNED_FILES_BYTES) { const deps = dependencies.get(manifest)
trunc_at = index if (deps) {
break const dependencyNames = deps.map(
} dependency => `<li>${dependency.name}@${dependency.version}</li>`
sf_size += entry.length )
} summary.addDetails(manifest, `<ul>${dependencyNames.join('')}</ul>`)
if (trunc_at >= 0) {
// truncate the manifests list if it will overflow the summary output
manifests.slice(0, trunc_at)
// if there's room between cutoff size and list size, add a warning
const size_diff = MAX_SCANNED_FILES_BYTES - sf_size
if (size_diff < 12) {
manifests.push('(truncated)')
} }
} }
core.summary.addHeading('Scanned Files', 2).addList(manifests)
} }
function snapshotWarningRecommendation( function snapshotWarningRecommendation(
+2
View File
@@ -13,4 +13,6 @@ declare module '@onebeyond/spdx-license-satisfies' {
candidateExpr: string, candidateExpr: string,
licenses: string[] licenses: string[]
): boolean ): boolean
export function isValid(candidateExpr: string): boolean
} }