Skip to content

Commit

Permalink
Merge branch 'main' into deps-dev-v3
Browse files Browse the repository at this point in the history
  • Loading branch information
josieang committed May 6, 2024
2 parents 2a28e93 + 82ab8f6 commit d11eeb3
Show file tree
Hide file tree
Showing 19 changed files with 783 additions and 469 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ Here are a few things you can do that will increase the likelihood of your pull

## Cutting a new release

1. Update the version number in [package.json](https://github.com/actions/dependency-review-action/blob/main/package.json).
1. Update the version number in [package.json](https://github.com/actions/dependency-review-action/blob/main/package.json) and run `npm i` to update the lockfile.
1. Go to [Draft a new
release](https://github.com/actions/dependency-review-action/releases/new)
in the Releases page.
Expand Down
46 changes: 46 additions & 0 deletions __tests__/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,52 @@ test('it raises an error if an empty allow list is specified', async () => {
)
})

test('it successfully parses allow-dependencies-licenses', async () => {
setInput(
'allow-dependencies-licenses',
'pkg:npm/@test/package@1.2.3,pkg:npm/example'
)
const config = await readConfig()
expect(config.allow_dependencies_licenses).toEqual([
'pkg:npm/@test/package@1.2.3',
'pkg:npm/example'
])
})

test('it raises an error when an invalid package-url is used for allow-dependencies-licenses', async () => {
setInput('allow-dependencies-licenses', '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 allow-dependencies-licenses', async () => {
setInput('allow-dependencies-licenses', 'pkg:npm/@namespace/')
await expect(readConfig()).rejects.toThrow(
`Error parsing package-url: name is required`
)
})

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')

Expand Down
19 changes: 19 additions & 0 deletions __tests__/deny.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand Down
3 changes: 1 addition & 2 deletions __tests__/fixtures/create-test-change.ts
Original file line number Diff line number Diff line change
@@ -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',
Expand Down
186 changes: 186 additions & 0 deletions __tests__/purl.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
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:golang/gopkg.in/DataDog/dd-trace-go.v1@1.63.1',
// Note: this purl is technically invalid, but we can still parse it
expected: {
type: 'golang',
namespace: 'gopkg.in',
name: 'DataDog/dd-trace-go.v1',
version: '1.63.1',
original: 'pkg:golang/gopkg.in/DataDog/dd-trace-go.v1@1.63.1',
error: null
}
},
{
purl: 'pkg:golang/github.com/pelletier/go-toml/v2',
// Note: this purl is technically invalid, but we can still parse it
expected: {
type: 'golang',
namespace: 'github.com',
name: 'pelletier/go-toml/v2',
version: null,
original: 'pkg:golang/github.com/pelletier/go-toml/v2',
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)
}
})
5 changes: 4 additions & 1 deletion __tests__/test-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export function clearInputs(): void {
'FAIL-ON-SEVERITY',
'FAIL-ON-SCOPES',
'ALLOW-LICENSES',
'ALLOW-DEPENDENCIES-LICENSES',
'DENY-LICENSES',
'ALLOW-GHSAS',
'LICENSE-CHECK',
Expand All @@ -19,7 +20,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
Expand Down
2 changes: 1 addition & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit d11eeb3

Please sign in to comment.