linting and unit testing

This commit is contained in:
Michael Waddell
2022-02-17 20:32:55 -06:00
parent d5d6d4da96
commit 4d5384fc6f
7 changed files with 229 additions and 90 deletions

107
dist/index.js generated vendored
View File

@@ -13401,33 +13401,80 @@ function warnOtherCommits() {
"Try using '@dependabot rebase' to remove merge commits or '@dependabot recreate' to remove " +
'any non-Dependabot changes.');
}
function getAlert(name, version, directory, client, context) {
var _a, _b, _c, _d, _e;
return __awaiter(this, void 0, void 0, function* () {
const alerts = yield client.graphql(`
{
repository(owner: "${context.repo.owner}", name: "${context.repo.repo}") {
vulnerabilityAlerts(first: 100) {
nodes {
vulnerableManifestFilename
vulnerableManifestPath
vulnerableRequirements
state
securityVulnerability {
package { name }
}
securityAdvisory {
cvss { score }
ghsaId
}
}
}
}
}`);
const nodes = (_b = (_a = alerts === null || alerts === void 0 ? void 0 : alerts.repository) === null || _a === void 0 ? void 0 : _a.vulnerabilityAlerts) === null || _b === void 0 ? void 0 : _b.nodes;
const found = nodes.find(a => a.vulnerableRequirements === `= ${version}` &&
trimSlashes(a.vulnerableManifestPath) === `${trimSlashes(directory)}/${a.vulnerableManifestFilename}` &&
a.securityVulnerability.package.name === name);
return {
alertState: (_c = found === null || found === void 0 ? void 0 : found.state) !== null && _c !== void 0 ? _c : '',
ghsaId: (_d = found === null || found === void 0 ? void 0 : found.securityAdvisory.ghsaId) !== null && _d !== void 0 ? _d : '',
cvss: (_e = found === null || found === void 0 ? void 0 : found.securityAdvisory.cvss.score) !== null && _e !== void 0 ? _e : 0.0
};
});
}
function trimSlashes(value) {
return value.replace(/^\//, '').replace(/\/$/, '');
}
// EXTERNAL MODULE: ./node_modules/yaml/index.js
var yaml = __nccwpck_require__(3552);
;// CONCATENATED MODULE: ./src/dependabot/update_metadata.ts
var update_metadata_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
function parse(commitMessage, branchName, mainBranch) {
const yamlFragment = commitMessage.match(/^-{3}\n(?<dependencies>[\S|\s]*?)\n^\.{3}\n/m);
if ((yamlFragment === null || yamlFragment === void 0 ? void 0 : yamlFragment.groups) && branchName.startsWith('dependabot')) {
const data = yaml.parse(yamlFragment.groups.dependencies);
// Since we are on the `dependabot` branch (9 letters), the 10th letter in the branch name is the delimiter
const delim = branchName[10];
const chunks = branchName.split(delim);
const dirname = chunks.slice(2, -1).join(delim) || '/';
if (data['updated-dependencies']) {
return data['updated-dependencies'].map(dependency => {
return {
dependencyName: dependency['dependency-name'],
dependencyType: dependency['dependency-type'],
updateType: dependency['update-type'],
directory: dirname,
packageEcosystem: chunks[1],
targetBranch: mainBranch
};
});
function parse(commitMessage, branchName, mainBranch, lookup) {
var _a, _b, _c, _d, _e, _f;
return update_metadata_awaiter(this, void 0, void 0, function* () {
const firstLine = commitMessage.split('\n')[0];
const directory = firstLine.match(/ in (?<directory>\/[^ ]*)$/);
const bumpFragment = commitMessage.match(/^Bumps .* from (?<from>\d[^ ]*) to (?<to>\d[^ ]*)\.$/m);
const yamlFragment = commitMessage.match(/^-{3}\n(?<dependencies>[\S|\s]*?)\n^\.{3}\n/m);
if ((yamlFragment === null || yamlFragment === void 0 ? void 0 : yamlFragment.groups) && branchName.startsWith('dependabot')) {
const data = yaml.parse(yamlFragment.groups.dependencies);
// Since we are on the `dependabot` branch (9 letters), the 10th letter in the branch name is the delimiter
const delim = branchName[10];
const chunks = branchName.split(delim);
const dirname = (_b = (_a = directory === null || directory === void 0 ? void 0 : directory.groups) === null || _a === void 0 ? void 0 : _a.directory) !== null && _b !== void 0 ? _b : '/';
const prev = (_d = (_c = bumpFragment === null || bumpFragment === void 0 ? void 0 : bumpFragment.groups) === null || _c === void 0 ? void 0 : _c.from) !== null && _d !== void 0 ? _d : '';
const next = (_f = (_e = bumpFragment === null || bumpFragment === void 0 ? void 0 : bumpFragment.groups) === null || _e === void 0 ? void 0 : _e.to) !== null && _f !== void 0 ? _f : '';
if (data['updated-dependencies']) {
return yield Promise.all(data['updated-dependencies'].map((dependency) => update_metadata_awaiter(this, void 0, void 0, function* () {
return (Object.assign({ dependencyName: dependency['dependency-name'], dependencyType: dependency['dependency-type'], updateType: dependency['update-type'], directory: dirname, packageEcosystem: chunks[1], targetBranch: mainBranch, prevVersion: prev, newVersion: next }, yield lookup(dependency['dependency-name'], prev, dirname)));
})));
}
}
}
return [];
return Promise.resolve([]);
});
}
// EXTERNAL MODULE: ./node_modules/pluralize/pluralize.js
@@ -13456,6 +13503,11 @@ function set(updatedDependencies) {
const directory = firstDependency === null || firstDependency === void 0 ? void 0 : firstDependency.directory;
const ecosystem = firstDependency === null || firstDependency === void 0 ? void 0 : firstDependency.packageEcosystem;
const target = firstDependency === null || firstDependency === void 0 ? void 0 : firstDependency.targetBranch;
const prevVersion = firstDependency === null || firstDependency === void 0 ? void 0 : firstDependency.prevVersion;
const newVersion = firstDependency === null || firstDependency === void 0 ? void 0 : firstDependency.newVersion;
const alertState = firstDependency === null || firstDependency === void 0 ? void 0 : firstDependency.alertState;
const ghsaId = firstDependency === null || firstDependency === void 0 ? void 0 : firstDependency.ghsaId;
const cvss = firstDependency === null || firstDependency === void 0 ? void 0 : firstDependency.cvss;
core.startGroup(`Outputting metadata for ${pluralize_default()('updated dependency', updatedDependencies.length, true)}`);
core.info(`outputs.dependency-names: ${dependencyNames}`);
core.info(`outputs.dependency-type: ${dependencyType}`);
@@ -13463,6 +13515,11 @@ function set(updatedDependencies) {
core.info(`outputs.directory: ${directory}`);
core.info(`outputs.package-ecosystem: ${ecosystem}`);
core.info(`outputs.target-branch: ${target}`);
core.info(`outputs.previous-version: ${prevVersion}`);
core.info(`outputs.new-version: ${newVersion}`);
core.info(`outputs.alert-state: ${alertState}`);
core.info(`outputs.ghsa-id: ${ghsaId}`);
core.info(`outputs.cvss: ${cvss}`);
core.endGroup();
core.setOutput('updated-dependencies-json', updatedDependencies);
core.setOutput('dependency-names', dependencyNames);
@@ -13471,6 +13528,11 @@ function set(updatedDependencies) {
core.setOutput('directory', directory);
core.setOutput('package-ecosystem', ecosystem);
core.setOutput('target-branch', target);
core.setOutput('previous-version', prevVersion);
core.setOutput('new-version', newVersion);
core.setOutput('alert-state', alertState);
core.setOutput('ghsa-id', ghsaId);
core.setOutput('cvss', cvss);
}
function maxDependencyTypes(updatedDependencies) {
const dependencyTypes = updatedDependencies.reduce(function (dependencyTypes, dependency) {
@@ -13531,10 +13593,11 @@ function run() {
// Validate the job
const commitMessage = yield getMessage(githubClient, github.context);
const branchNames = getBranchNames(github.context);
const alertLookup = (name, version, directory) => getAlert(name, version, directory, githubClient, github.context);
if (commitMessage) {
// Parse metadata
core.info('Parsing Dependabot metadata');
const updatedDependencies = parse(commitMessage, branchNames.headName, branchNames.baseName);
const updatedDependencies = yield parse(commitMessage, branchNames.headName, branchNames.baseName, alertLookup);
if (updatedDependencies.length > 0) {
set(updatedDependencies);
}

View File

@@ -9,6 +9,20 @@ beforeEach(() => {
jest.spyOn(core, 'startGroup').mockImplementation(jest.fn())
})
const baseDependency = {
dependencyName: '',
dependencyType: '',
updateType: '',
directory: '',
packageEcosystem: '',
targetBranch: '',
prevVersion: '',
newVersion: '',
alertState: '',
ghsaId: '',
cvss: 0
}
test('when given a single dependency it sets its values', async () => {
const updatedDependencies = [
{
@@ -17,7 +31,12 @@ test('when given a single dependency it sets its values', async () => {
updateType: 'version-update:semver-minor',
directory: 'wwwroot',
packageEcosystem: 'nuget',
targetBranch: 'main'
targetBranch: 'main',
prevVersion: '1.0.2',
newVersion: '1.1.3-beta',
alertState: 'FIXED',
ghsaId: 'VERY_LONG_ID',
cvss: 4.6
}
]
@@ -40,36 +59,28 @@ test('when given a single dependency it sets its values', async () => {
test('when given a multiple dependencies, it uses the highest values for types', async () => {
const updatedDependencies = [
{
...baseDependency,
dependencyName: 'rspec',
dependencyType: 'direct:development',
updateType: 'version-update:semver-minor',
directory: '',
packageEcosystem: '',
targetBranch: ''
updateType: 'version-update:semver-minor'
},
{
...baseDependency,
dependencyName: 'coffee-rails',
dependencyType: 'indirect',
updateType: 'version-update:semver-minor',
directory: '',
packageEcosystem: '',
targetBranch: ''
updateType: 'version-update:semver-minor'
},
{
...baseDependency,
dependencyName: 'coffeescript',
dependencyType: 'indirect',
updateType: 'version-update:semver-major',
directory: '',
packageEcosystem: '',
targetBranch: ''
updateType: 'version-update:semver-major'
},
{
...baseDependency,
dependencyName: 'rspec-coffeescript',
dependencyType: 'indirect',
updateType: 'version-update:semver-patch',
directory: '',
packageEcosystem: '',
targetBranch: ''
updateType: 'version-update:semver-patch'
}
]
@@ -88,12 +99,9 @@ test('when given a multiple dependencies, it uses the highest values for types',
test('when the dependency has no update type', async () => {
const updatedDependencies = [
{
...baseDependency,
dependencyName: 'coffee-rails',
dependencyType: 'direct:production',
updateType: '',
directory: '',
packageEcosystem: '',
targetBranch: ''
dependencyType: 'direct:production'
}
]
@@ -116,36 +124,26 @@ test('when the dependency has no update type', async () => {
test('when given a multiple dependencies, and some do not have update types', async () => {
const updatedDependencies = [
{
...baseDependency,
dependencyName: 'rspec',
dependencyType: 'direct:development',
updateType: '',
directory: '',
packageEcosystem: '',
targetBranch: ''
dependencyType: 'direct:development'
},
{
...baseDependency,
dependencyName: 'coffee-rails',
dependencyType: 'indirect',
updateType: 'version-update:semver-minor',
directory: '',
packageEcosystem: '',
targetBranch: ''
updateType: 'version-update:semver-minor'
},
{
...baseDependency,
dependencyName: 'coffeescript',
dependencyType: 'indirect',
updateType: '',
directory: '',
packageEcosystem: '',
targetBranch: ''
dependencyType: 'indirect'
},
{
...baseDependency,
dependencyName: 'rspec-coffeescript',
dependencyType: 'indirect',
updateType: 'version-update:semver-patch',
directory: '',
packageEcosystem: '',
targetBranch: ''
updateType: 'version-update:semver-patch'
}
]

View File

@@ -24,6 +24,11 @@ export function set (updatedDependencies: Array<updatedDependency>): void {
const directory = firstDependency?.directory
const ecosystem = firstDependency?.packageEcosystem
const target = firstDependency?.targetBranch
const prevVersion = firstDependency?.prevVersion
const newVersion = firstDependency?.newVersion
const alertState = firstDependency?.alertState
const ghsaId = firstDependency?.ghsaId
const cvss = firstDependency?.cvss
core.startGroup(`Outputting metadata for ${Pluralize('updated dependency', updatedDependencies.length, true)}`)
core.info(`outputs.dependency-names: ${dependencyNames}`)
@@ -32,6 +37,11 @@ export function set (updatedDependencies: Array<updatedDependency>): void {
core.info(`outputs.directory: ${directory}`)
core.info(`outputs.package-ecosystem: ${ecosystem}`)
core.info(`outputs.target-branch: ${target}`)
core.info(`outputs.previous-version: ${prevVersion}`)
core.info(`outputs.new-version: ${newVersion}`)
core.info(`outputs.alert-state: ${alertState}`)
core.info(`outputs.ghsa-id: ${ghsaId}`)
core.info(`outputs.cvss: ${cvss}`)
core.endGroup()
core.setOutput('updated-dependencies-json', updatedDependencies)
@@ -41,6 +51,11 @@ export function set (updatedDependencies: Array<updatedDependency>): void {
core.setOutput('directory', directory)
core.setOutput('package-ecosystem', ecosystem)
core.setOutput('target-branch', target)
core.setOutput('previous-version', prevVersion)
core.setOutput('new-version', newVersion)
core.setOutput('alert-state', alertState)
core.setOutput('ghsa-id', ghsaId)
core.setOutput('cvss', cvss)
}
function maxDependencyTypes (updatedDependencies: Array<updatedDependency>): string {

View File

@@ -1,22 +1,26 @@
import * as updateMetadata from './update_metadata'
test('it returns an empty array for a blank string', async () => {
expect(updateMetadata.parse('', 'dependabot/nuget/feature1', 'main')).toEqual([])
const getAlert = async () => Promise.resolve({ alertState: 'DISMISSED', ghsaId: 'GHSA-III-BBB', cvss: 4.6 })
expect(updateMetadata.parse('', 'dependabot/nuget/feature1', 'main', getAlert)).resolves.toEqual([])
})
test('it returns an empty array for commit message with no dependabot yaml fragment', async () => {
const commitMessage = `Bumps [coffee-rails](https://github.com/rails/coffee-rails) from 4.0.1 to 4.2.2.
const commitMessage = `Bump coffee-rails from 4.0.1 to 4.2.2
Bumps [coffee-rails](https://github.com/rails/coffee-rails) from 4.0.1 to 4.2.2.
- [Release notes](https://github.com/rails/coffee-rails/releases)
- [Changelog](https://github.com/rails/coffee-rails/blob/master/CHANGELOG.md)
- [Commits](rails/coffee-rails@v4.0.1...v4.2.2)
Signed-off-by: dependabot[bot] <support@github.com>`
expect(updateMetadata.parse(commitMessage, 'dependabot/nuget/feature1', 'main')).toEqual([])
const getAlert = async () => Promise.resolve({ alertState: 'DISMISSED', ghsaId: 'GHSA-III-BBB', cvss: 4.6 })
expect(updateMetadata.parse(commitMessage, 'dependabot/nuget/feature1', 'main', getAlert)).resolves.toEqual([])
})
test('it returns the updated dependency information when there is a yaml fragment', async () => {
const commitMessage =
'Bump coffee-rails from 4.0.1 to 4.2.2\n' +
'Bumps [coffee-rails](https://github.com/rails/coffee-rails) from 4.0.1 to 4.2.2.\n' +
'- [Release notes](https://github.com/rails/coffee-rails/releases)\n' +
'- [Changelog](https://github.com/rails/coffee-rails/blob/master/CHANGELOG.md)\n' +
@@ -31,7 +35,8 @@ test('it returns the updated dependency information when there is a yaml fragmen
'\n' +
'Signed-off-by: dependabot[bot] <support@github.com>'
const updatedDependencies = updateMetadata.parse(commitMessage, 'dependabot/nuget/feature1', 'main')
const getAlert = async () => Promise.resolve({ alertState: 'DISMISSED', ghsaId: 'GHSA-III-BBB', cvss: 4.6 })
const updatedDependencies = await updateMetadata.parse(commitMessage, 'dependabot/nuget/feature1', 'main', getAlert)
expect(updatedDependencies).toHaveLength(1)
@@ -41,10 +46,16 @@ test('it returns the updated dependency information when there is a yaml fragmen
expect(updatedDependencies[0].directory).toEqual('/')
expect(updatedDependencies[0].packageEcosystem).toEqual('nuget')
expect(updatedDependencies[0].targetBranch).toEqual('main')
expect(updatedDependencies[0].prevVersion).toEqual('4.0.1')
expect(updatedDependencies[0].newVersion).toEqual('4.2.2')
expect(updatedDependencies[0].alertState).toEqual('DISMISSED')
expect(updatedDependencies[0].ghsaId).toEqual('GHSA-III-BBB')
expect(updatedDependencies[0].cvss).toEqual(4.6)
})
test('it supports multiple dependencies within a single fragment', async () => {
const commitMessage =
'Bump coffee-rails from 4.0.1 to 4.2.2 in /api/main\n' +
'Bumps [coffee-rails](https://github.com/rails/coffee-rails) from 4.0.1 to 4.2.2.\n' +
'- [Release notes](https://github.com/rails/coffee-rails/releases)\n' +
'- [Changelog](https://github.com/rails/coffee-rails/blob/master/CHANGELOG.md)\n' +
@@ -62,28 +73,45 @@ test('it supports multiple dependencies within a single fragment', async () => {
'\n' +
'Signed-off-by: dependabot[bot] <support@github.com>'
const updatedDependencies = updateMetadata.parse(commitMessage, 'dependabot/nuget/api/main/feature1', 'main')
const getAlert = async (name: string) => {
if (name === 'coffee-rails') {
return Promise.resolve({ alertState: 'DISMISSED', ghsaId: 'GHSA-III-BBB', cvss: 4.6 })
}
return Promise.resolve({ alertState: '', ghsaId: '', cvss: 0 })
}
const updatedDependencies = await updateMetadata.parse(commitMessage, 'dependabot/nuget/api/main/feature1', 'main', getAlert)
expect(updatedDependencies).toHaveLength(2)
expect(updatedDependencies[0].dependencyName).toEqual('coffee-rails')
expect(updatedDependencies[0].dependencyType).toEqual('direct:production')
expect(updatedDependencies[0].updateType).toEqual('version-update:semver-minor')
expect(updatedDependencies[0].directory).toEqual('api/main')
expect(updatedDependencies[0].directory).toEqual('/api/main')
expect(updatedDependencies[0].packageEcosystem).toEqual('nuget')
expect(updatedDependencies[0].targetBranch).toEqual('main')
expect(updatedDependencies[0].prevVersion).toEqual('4.0.1')
expect(updatedDependencies[0].newVersion).toEqual('4.2.2')
expect(updatedDependencies[0].alertState).toEqual('DISMISSED')
expect(updatedDependencies[0].ghsaId).toEqual('GHSA-III-BBB')
expect(updatedDependencies[0].cvss).toEqual(4.6)
expect(updatedDependencies[1].dependencyName).toEqual('coffeescript')
expect(updatedDependencies[1].dependencyType).toEqual('indirect')
expect(updatedDependencies[1].updateType).toEqual('version-update:semver-patch')
expect(updatedDependencies[1].directory).toEqual('api/main')
expect(updatedDependencies[1].directory).toEqual('/api/main')
expect(updatedDependencies[1].packageEcosystem).toEqual('nuget')
expect(updatedDependencies[1].targetBranch).toEqual('main')
expect(updatedDependencies[1].prevVersion).toEqual('')
expect(updatedDependencies[1].newVersion).toEqual('')
expect(updatedDependencies[1].alertState).toEqual('')
expect(updatedDependencies[1].ghsaId).toEqual('')
expect(updatedDependencies[1].cvss).toEqual(0)
})
test('it only returns information within the first fragment if there are multiple yaml documents', async () => {
const commitMessage =
'Bumps [coffee-rails](https://github.com/rails/coffee-rails) from 4.0.1 to 4.2.2.\n' +
'- [Release notes](https://github.com/rails/coffee-rails/releases)\n' +
'- [Changelog](https://github.com/rails/coffee-rails/blob/master/CHANGELOG.md)\n' +
'- [Commits](rails/coffee-rails@v4.0.1...v4.2.2)\n' +
@@ -104,14 +132,20 @@ test('it only returns information within the first fragment if there are multipl
'\n' +
'Signed-off-by: dependabot[bot] <support@github.com>'
const updatedDependencies = updateMetadata.parse(commitMessage, 'dependabot|nuget|api|feature1', 'main')
const getAlert = async () => Promise.resolve({ alertState: '', ghsaId: '', cvss: 0 })
const updatedDependencies = await updateMetadata.parse(commitMessage, 'dependabot|nuget|feature1', 'main', getAlert)
expect(updatedDependencies).toHaveLength(1)
expect(updatedDependencies[0].dependencyName).toEqual('coffee-rails')
expect(updatedDependencies[0].dependencyType).toEqual('direct:production')
expect(updatedDependencies[0].updateType).toEqual('version-update:semver-minor')
expect(updatedDependencies[0].directory).toEqual('api')
expect(updatedDependencies[0].directory).toEqual('/')
expect(updatedDependencies[0].packageEcosystem).toEqual('nuget')
expect(updatedDependencies[0].targetBranch).toEqual('main')
expect(updatedDependencies[0].prevVersion).toEqual('')
expect(updatedDependencies[0].newVersion).toEqual('')
expect(updatedDependencies[0].alertState).toEqual('')
expect(updatedDependencies[0].ghsaId).toEqual('')
expect(updatedDependencies[0].cvss).toEqual(0)
})

View File

@@ -23,7 +23,7 @@ export interface alertLookup {
export async function parse (commitMessage: string, branchName: string, mainBranch: string, lookup: alertLookup): Promise<Array<updatedDependency>> {
const firstLine = commitMessage.split('\n')[0]
const directory = firstLine.match(/ in (?<directory>\/[^ ]*)$/)
const directory = firstLine.match(/ in (?<directory>[^ ]+)$/)
const bumpFragment = commitMessage.match(/^Bumps .* from (?<from>\d[^ ]*) to (?<to>\d[^ ]*)\.$/m)
const yamlFragment = commitMessage.match(/^-{3}\n(?<dependencies>[\S|\s]*?)\n^\.{3}\n/m)
@@ -33,21 +33,21 @@ export async function parse (commitMessage: string, branchName: string, mainBran
// Since we are on the `dependabot` branch (9 letters), the 10th letter in the branch name is the delimiter
const delim = branchName[10]
const chunks = branchName.split(delim)
const dirname = directory?.groups?.directory ?? "/"
const prev = bumpFragment?.groups?.from ?? ""
const next = bumpFragment?.groups?.to ?? ""
const dirname = directory?.groups?.directory ?? '/'
const prev = bumpFragment?.groups?.from ?? ''
const next = bumpFragment?.groups?.to ?? ''
if (data['updated-dependencies']) {
return await Promise.all(data['updated-dependencies'].map(async (dependency) => ({
return await Promise.all(data['updated-dependencies'].map(async (dependency, index) => ({
dependencyName: dependency['dependency-name'],
dependencyType: dependency['dependency-type'],
updateType: dependency['update-type'],
directory: dirname,
packageEcosystem: chunks[1],
targetBranch: mainBranch,
prevVersion: prev,
newVersion: next,
...await lookup(dependency['dependency-name'], prev, dirname)
prevVersion: index === 0 ? prev : "",
newVersion: index === 0 ? next : "",
...await lookup(dependency['dependency-name'], index === 0 ? prev : "", dirname)
})))
}
}

View File

@@ -86,17 +86,17 @@ export async function getAlert (name: string, version: string, directory: string
}`)
const nodes = alerts?.repository?.vulnerabilityAlerts?.nodes
const found = nodes.find(a => a.vulnerableRequirements == `= ${version}`
&& trimSlashes(a.vulnerableManifestPath) == `${trimSlashes(directory)}/${a.vulnerableManifestFilename}`
&& a.securityVulnerability.package.name == name)
const found = nodes.find(a => (version === '' || a.vulnerableRequirements === `= ${version}`) &&
trimSlashes(a.vulnerableManifestPath) === `${trimSlashes(directory)}/${a.vulnerableManifestFilename}` &&
a.securityVulnerability.package.name === name)
return {
alertState: found?.state ?? "",
ghsaId: found?.securityAdvisory.ghsaId ?? "",
return {
alertState: found?.state ?? '',
ghsaId: found?.securityAdvisory.ghsaId ?? '',
cvss: found?.securityAdvisory.cvss.score ?? 0.0
}
}
export function trimSlashes(value: string): string {
export function trimSlashes (value: string): string {
return value.replace(/^\//, '').replace(/\/$/, '')
}

View File

@@ -23,6 +23,7 @@ test('it early exits with an error if github-token is not set', async () => {
)
/* eslint-disable no-unused-expressions */
expect(dependabotCommits.getMessage).not.toHaveBeenCalled
expect(dependabotCommits.getAlert).not.toHaveBeenCalled
/* eslint-enable no-unused-expressions */
})
@@ -38,6 +39,7 @@ test('it does nothing if the PR is not verified as from Dependabot', async () =>
expect(core.setFailed).toHaveBeenCalledWith(
expect.stringContaining('PR is not from Dependabot, nothing to do.')
)
expect(dependabotCommits.getAlert).not.toHaveBeenCalled
})
test('it does nothing if there is no metadata in the commit', async () => {
@@ -52,6 +54,7 @@ test('it does nothing if there is no metadata in the commit', async () => {
expect(core.setFailed).toHaveBeenCalledWith(
expect.stringContaining('PR does not contain metadata, nothing to do.')
)
expect(dependabotCommits.getAlert).not.toHaveBeenCalled
})
test('it sets the updated dependency as an output for subsequent actions', async () => {
@@ -69,12 +72,16 @@ test('it sets the updated dependency as an output for subsequent actions', async
'...\n' +
'\n' +
'Signed-off-by: dependabot[bot] <support@github.com>'
const mockAlert = { alertState: "FIXED", ghsaId: "GSHA", cvss: 3.4 }
jest.spyOn(core, 'getInput').mockReturnValue('mock-token')
jest.spyOn(util, 'getBranchNames').mockReturnValue({ headName: 'dependabot|nuget|feature1', baseName: 'main' })
jest.spyOn(dependabotCommits, 'getMessage').mockImplementation(jest.fn(
() => Promise.resolve(mockCommitMessage)
))
jest.spyOn(dependabotCommits, 'getAlert').mockImplementation(jest.fn(
() => Promise.resolve(mockAlert)
))
jest.spyOn(core, 'setOutput').mockImplementation(jest.fn())
await run()
@@ -92,7 +99,12 @@ test('it sets the updated dependency as an output for subsequent actions', async
updateType: 'version-update:semver-minor',
directory: '/',
packageEcosystem: 'nuget',
targetBranch: 'main'
targetBranch: 'main',
prevVersion: '4.0.1',
newVersion: '4.2.2',
alertState: 'FIXED',
ghsaId: 'GSHA',
cvss: 3.4
}
]
)
@@ -107,6 +119,7 @@ test('it sets the updated dependency as an output for subsequent actions', async
test('if there are multiple dependencies, it summarizes them', async () => {
const mockCommitMessage =
'Bump coffee-rails from 4.0.1 to 4.2.2 in api/main\n' +
'Bumps [coffee-rails](https://github.com/rails/coffee-rails) from 4.0.1 to 4.2.2.\n' +
'- [Release notes](https://github.com/rails/coffee-rails/releases)\n' +
'- [Changelog](https://github.com/rails/coffee-rails/blob/master/CHANGELOG.md)\n' +
@@ -123,12 +136,16 @@ test('if there are multiple dependencies, it summarizes them', async () => {
'...\n' +
'\n' +
'Signed-off-by: dependabot[bot] <support@github.com>'
const mockAlert = { alertState: "", ghsaId: "", cvss: 0 }
jest.spyOn(core, 'getInput').mockReturnValue('mock-token')
jest.spyOn(util, 'getBranchNames').mockReturnValue({ headName: 'dependabot/npm_and_yarn/api/main/feature1', baseName: 'trunk' })
jest.spyOn(dependabotCommits, 'getMessage').mockImplementation(jest.fn(
() => Promise.resolve(mockCommitMessage)
))
jest.spyOn(dependabotCommits, 'getAlert').mockImplementation(jest.fn(
() => Promise.resolve(mockAlert)
))
jest.spyOn(core, 'setOutput').mockImplementation(jest.fn())
await run()
@@ -146,7 +163,12 @@ test('if there are multiple dependencies, it summarizes them', async () => {
updateType: 'version-update:semver-minor',
directory: 'api/main',
packageEcosystem: 'npm_and_yarn',
targetBranch: 'trunk'
targetBranch: 'trunk',
prevVersion: '4.0.1',
newVersion: '4.2.2',
alertState: '',
ghsaId: '',
cvss: 0
},
{
dependencyName: 'coffeescript',
@@ -154,7 +176,12 @@ test('if there are multiple dependencies, it summarizes them', async () => {
updateType: 'version-update:semver-major',
directory: 'api/main',
packageEcosystem: 'npm_and_yarn',
targetBranch: 'trunk'
targetBranch: 'trunk',
prevVersion: '',
newVersion: '',
alertState: '',
ghsaId: '',
cvss: 0
}
]
)
@@ -176,6 +203,7 @@ test('it sets the action to failed if there is an unexpected exception', async (
await run()
expect(dependabotCommits.getAlert).not.toHaveBeenCalled
expect(core.setFailed).toHaveBeenCalledWith(
expect.stringContaining('Something bad happened!')
)
@@ -199,6 +227,7 @@ test('it sets the action to failed if there is a request error', async () => {
await run()
expect(dependabotCommits.getAlert).not.toHaveBeenCalled
expect(core.setFailed).toHaveBeenCalledWith(
expect.stringContaining('(500) Something bad happened!')
)