Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05042db2b6 | ||
|
|
6aacbe0934 | ||
|
|
293ccdb6e9 | ||
|
|
83c7cc6aa7 | ||
|
|
b3559aa82e | ||
|
|
8179e6abd6 | ||
|
|
526b7f2f9b | ||
|
|
e5cb30f678 | ||
|
|
90820aba8c | ||
|
|
7367319600 | ||
|
|
07d3c7257a |
+1
-1
@@ -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, 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 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'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.
|
||||||
|
|
||||||
|
|||||||
@@ -109,42 +109,6 @@ 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
|
||||||
|
|
||||||
@@ -232,14 +196,10 @@ test('groups dependencies with empty manifest paths together', () => {
|
|||||||
emptyScorecard,
|
emptyScorecard,
|
||||||
defaultConfig
|
defaultConfig
|
||||||
)
|
)
|
||||||
summary.addScannedDependencies(changesWithEmptyManifests)
|
summary.addScannedFiles(changesWithEmptyManifests)
|
||||||
const text = core.summary.stringify()
|
const text = core.summary.stringify()
|
||||||
|
expect(text).toContain('Unnamed Manifest')
|
||||||
expect(text).toContain('<summary>Unnamed Manifest</summary>')
|
expect(text).toContain('python/dist-info/METADATA')
|
||||||
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', () => {
|
||||||
|
|||||||
+23
-12
@@ -705,7 +705,7 @@ function run() {
|
|||||||
createScorecardWarnings(scorecard, config);
|
createScorecardWarnings(scorecard, config);
|
||||||
}
|
}
|
||||||
core.setOutput('dependency-changes', JSON.stringify(changes));
|
core.setOutput('dependency-changes', JSON.stringify(changes));
|
||||||
summary.addScannedDependencies(changes);
|
summary.addScannedFiles(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
|
||||||
let rendered = core.summary.stringify();
|
let rendered = core.summary.stringify();
|
||||||
@@ -1442,7 +1442,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.addDeniedToSummary = exports.addSnapshotWarnings = exports.addScorecardToSummary = exports.addScannedDependencies = exports.addLicensesToSummary = exports.addChangeVulnerabilitiesToSummary = exports.addSummaryToSummary = void 0;
|
exports.addDeniedToSummary = exports.addSnapshotWarnings = exports.addScorecardToSummary = exports.addScannedFiles = exports.addLicensesToSummary = exports.addChangeVulnerabilitiesToSummary = exports.addSummaryToSummary = void 0;
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const utils_1 = __nccwpck_require__(918);
|
const utils_1 = __nccwpck_require__(918);
|
||||||
const icons = {
|
const icons = {
|
||||||
@@ -1450,6 +1450,7 @@ const icons = {
|
|||||||
cross: '❌',
|
cross: '❌',
|
||||||
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
|
||||||
@@ -1631,19 +1632,29 @@ function formatLicense(license) {
|
|||||||
}
|
}
|
||||||
return license;
|
return license;
|
||||||
}
|
}
|
||||||
function addScannedDependencies(changes) {
|
function addScannedFiles(changes) {
|
||||||
const dependencies = (0, utils_1.groupDependenciesByManifest)(changes);
|
const manifests = Array.from((0, utils_1.groupDependenciesByManifest)(changes).keys()).sort();
|
||||||
const manifests = dependencies.keys();
|
let sf_size = 0;
|
||||||
const summary = core.summary.addHeading('Scanned Manifest Files', 2);
|
let trunc_at = -1;
|
||||||
for (const manifest of manifests) {
|
for (const [index, entry] of manifests.entries()) {
|
||||||
const deps = dependencies.get(manifest);
|
if (sf_size + entry.length >= MAX_SCANNED_FILES_BYTES) {
|
||||||
if (deps) {
|
trunc_at = index;
|
||||||
const dependencyNames = deps.map(dependency => `<li>${dependency.name}@${dependency.version}</li>`);
|
break;
|
||||||
summary.addDetails(manifest, `<ul>${dependencyNames.join('')}</ul>`);
|
}
|
||||||
|
sf_size += entry.length;
|
||||||
|
}
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
exports.addScannedDependencies = addScannedDependencies;
|
exports.addScannedFiles = addScannedFiles;
|
||||||
function snapshotWarningRecommendation(config, warnings) {
|
function snapshotWarningRecommendation(config, warnings) {
|
||||||
const no_pr_snaps = warnings.includes('No snapshots were found for the head SHA');
|
const no_pr_snaps = warnings.includes('No snapshots were found for the head SHA');
|
||||||
const retries_disabled = !config.retry_on_snapshot_warnings;
|
const retries_disabled = !config.retry_on_snapshot_warnings;
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
Generated
+12
-11
@@ -2105,11 +2105,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "20.11.28",
|
"version": "20.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.28.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.0.tgz",
|
||||||
"integrity": "sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==",
|
"integrity": "sha512-vDxceJcoZhIVh67S568bm1UGZO0DX0hpplJZxzeXMKwIPLn190ec5RRxQ69BKhX44SUGIxxgMdDY557lGLKprQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~5.26.4"
|
"undici-types": "~6.19.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/semver": {
|
"node_modules/@types/semver": {
|
||||||
@@ -6341,11 +6341,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/micromatch": {
|
"node_modules/micromatch": {
|
||||||
"version": "4.0.5",
|
"version": "4.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||||
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
|
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"braces": "^3.0.2",
|
"braces": "^3.0.3",
|
||||||
"picomatch": "^2.3.1"
|
"picomatch": "^2.3.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -7913,9 +7914,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "5.26.5",
|
"version": "6.19.6",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.6.tgz",
|
||||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
"integrity": "sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org=="
|
||||||
},
|
},
|
||||||
"node_modules/universal-github-app-jwt": {
|
"node_modules/universal-github-app-jwt": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ async function createSummary(
|
|||||||
...licenseIssues.unlicensed
|
...licenseIssues.unlicensed
|
||||||
]
|
]
|
||||||
|
|
||||||
summary.addScannedDependencies(allChanges)
|
summary.addScannedFiles(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, {
|
||||||
|
|||||||
+1
-1
@@ -166,7 +166,7 @@ async function run(): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
core.setOutput('dependency-changes', JSON.stringify(changes))
|
core.setOutput('dependency-changes', JSON.stringify(changes))
|
||||||
summary.addScannedDependencies(changes)
|
summary.addScannedFiles(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
|
||||||
|
|||||||
+26
-12
@@ -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,6 +10,8 @@ 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
|
||||||
@@ -263,21 +265,33 @@ function formatLicense(license: string | null): string {
|
|||||||
return license
|
return license
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addScannedDependencies(changes: Changes): void {
|
export function addScannedFiles(changes: Changes): void {
|
||||||
const dependencies = groupDependenciesByManifest(changes)
|
const manifests = Array.from(
|
||||||
const manifests = dependencies.keys()
|
groupDependenciesByManifest(changes).keys()
|
||||||
|
).sort()
|
||||||
|
|
||||||
const summary = core.summary.addHeading('Scanned Manifest Files', 2)
|
let sf_size = 0
|
||||||
|
let trunc_at = -1
|
||||||
|
|
||||||
for (const manifest of manifests) {
|
for (const [index, entry] of manifests.entries()) {
|
||||||
const deps = dependencies.get(manifest)
|
if (sf_size + entry.length >= MAX_SCANNED_FILES_BYTES) {
|
||||||
if (deps) {
|
trunc_at = index
|
||||||
const dependencyNames = deps.map(
|
break
|
||||||
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(
|
||||||
|
|||||||
Reference in New Issue
Block a user