Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e77cc7329 | ||
|
|
b383a9aa6e | ||
|
|
8a49820431 | ||
|
|
a10a70d24c | ||
|
|
0de163860f | ||
|
|
522f0218d0 | ||
|
|
2597ca4eee | ||
|
|
e5c6735807 | ||
|
|
94f992f10e | ||
|
|
c45cbd720f | ||
|
|
2425542aca | ||
|
|
b39e17ba5e | ||
|
|
b8a398b675 | ||
|
|
1612de9646 | ||
|
|
53de591348 | ||
|
|
288d543806 | ||
|
|
359e1ffa80 | ||
|
|
63e1558807 | ||
|
|
069cbabe02 | ||
|
|
2e3c709016 | ||
|
|
01bc87099b | ||
|
|
4b4f0de8e1 | ||
|
|
a93fa86c77 | ||
|
|
550520e2c5 | ||
|
|
2d0fb60634 | ||
|
|
c07c2375ed | ||
|
|
4d842d754e | ||
|
|
a6d4686316 | ||
|
|
4366dbae42 | ||
|
|
50dafeb5e4 | ||
|
|
1cbb048907 | ||
|
|
ee69e92054 | ||
|
|
5991d7a97d | ||
|
|
c409735e58 | ||
|
|
7bbfa034e7 | ||
|
|
26f1ad9120 | ||
|
|
152d8e2def | ||
|
|
b99756ecd3 | ||
|
|
fde92acd08 | ||
|
|
a89dd96450 | ||
|
|
76891836b1 | ||
|
|
fc5e2db757 | ||
|
|
ded987cb3b | ||
|
|
9f45b2463b | ||
|
|
559513a56c | ||
|
|
8edc431d7d | ||
|
|
3e8322e4bb | ||
|
|
5a55885447 | ||
|
|
f952b5a2c5 | ||
|
|
8678cfac42 | ||
|
|
aa8e70d588 | ||
|
|
3331d25f9d | ||
|
|
2af83f55fa | ||
|
|
0d3cf5ba9e | ||
|
|
b2a5ead1f7 | ||
|
|
79f0a0b62b | ||
|
|
fc44602899 | ||
|
|
7177991451 | ||
|
|
90fe789d91 | ||
|
|
5cbf74f675 | ||
|
|
11e0dead9a | ||
|
|
3c1cb72dcd | ||
|
|
570a2b5dcd | ||
|
|
a7e01b8d9c | ||
|
|
168567cd17 | ||
|
|
1d86ff759b | ||
|
|
0631089c32 | ||
|
|
0b8ffde994 | ||
|
|
68d57cd360 | ||
|
|
7314a0c1f5 | ||
|
|
cfeea91bf4 | ||
|
|
c8515ab391 | ||
|
|
cff52fd316 | ||
|
|
e65eb02ccf | ||
|
|
88953c2b16 | ||
|
|
d97416955e | ||
|
|
523c9a28aa | ||
|
|
f85d4d5bc2 | ||
|
|
89ff65dbf7 | ||
|
|
c3c32181a9 | ||
|
|
ead6e4616f | ||
|
|
a265e18106 | ||
|
|
a8759965d7 | ||
|
|
954314c2b1 | ||
|
|
5b62f3bc06 | ||
|
|
fddf4c3474 | ||
|
|
04e56a4409 | ||
|
|
af51c4b700 | ||
|
|
bd3b04e194 | ||
|
|
382d2873a9 | ||
|
|
500120a761 | ||
|
|
212ded88b2 | ||
|
|
7ec89343e1 | ||
|
|
536cc3d4b6 | ||
|
|
2bc52c6348 | ||
|
|
fe9d8a52c4 | ||
|
|
bd251cc9eb | ||
|
|
7e65a9bb48 | ||
|
|
b91ea51364 | ||
|
|
76b050a607 | ||
|
|
e6d6badddb | ||
|
|
f7363549ac | ||
|
|
f71a906c2e | ||
|
|
03ace23f96 | ||
|
|
0564d6f4de | ||
|
|
cd09f857a3 | ||
|
|
69a61b613b | ||
|
|
53eb1ebcf5 | ||
|
|
8dc52cdbed | ||
|
|
e8634671a4 | ||
|
|
69ecf4db79 | ||
|
|
70835908ea | ||
|
|
f704f55fa1 | ||
|
|
e51d18ae1e | ||
|
|
62f26a66d6 | ||
|
|
2f836bbce6 | ||
|
|
75dbba1acf | ||
|
|
8325453339 | ||
|
|
353956d50d | ||
|
|
4e41165d4b | ||
|
|
cf3393ef0a | ||
|
|
8213a1db10 | ||
|
|
64a6d1a0b8 | ||
|
|
364de25b16 | ||
|
|
ad34390f92 | ||
|
|
1f5e4f1cd9 | ||
|
|
fcb0293419 | ||
|
|
6c530dbedd | ||
|
|
e5c6ae035a | ||
|
|
9c66f1b1b1 | ||
|
|
9add2f12fa | ||
|
|
079b962af9 | ||
|
|
e6b5e83d4e | ||
|
|
3c40a50e4b | ||
|
|
886d1fcf5f | ||
|
|
615671754c | ||
|
|
cd1bb8895d | ||
|
|
7095391667 | ||
|
|
6c5ccdad46 | ||
|
|
51da82b3f5 | ||
|
|
ca13810d94 | ||
|
|
8447b31d38 | ||
|
|
85df23de2c | ||
|
|
5da6fdbdf9 | ||
|
|
92837b0ca8 | ||
|
|
35a52fd146 | ||
|
|
bed9726f78 | ||
|
|
e4d20ce9ad | ||
|
|
bb0ca79fcd | ||
|
|
07f52ce621 | ||
|
|
c7e8727af4 | ||
|
|
5e4b90e080 | ||
|
|
7d0e0f61e8 | ||
|
|
ffaf251c92 | ||
|
|
726ffc8aa8 | ||
|
|
fcef41f1e0 | ||
|
|
e81e6e582f | ||
|
|
511675e747 | ||
|
|
dcdbff2f84 | ||
|
|
29513b58ad | ||
|
|
347cb43687 | ||
|
|
dfe37bb356 | ||
|
|
ada103783f | ||
|
|
abc80cf6a0 | ||
|
|
15e91a3980 | ||
|
|
c7d2795410 | ||
|
|
eb07c6d763 | ||
|
|
4d8fe1e464 | ||
|
|
ee86529290 | ||
|
|
c17dea4c51 | ||
|
|
727ca667a3 | ||
|
|
84cd472b61 | ||
|
|
366fffb717 | ||
|
|
62a1d2d370 | ||
|
|
42c2f7100f | ||
|
|
608049acca | ||
|
|
32037a1d97 | ||
|
|
f6fff72a32 | ||
|
|
61ee12c097 | ||
|
|
7d5babfc38 | ||
|
|
ddb1b9361c | ||
|
|
7c3177d3c2 | ||
|
|
31afeba06d | ||
|
|
7ef37f3853 | ||
|
|
2e59943778 | ||
|
|
902e86c6f5 | ||
|
|
d3fa764646 | ||
|
|
1856a6de19 | ||
|
|
5573b58443 | ||
|
|
c3c3c2e746 | ||
|
|
f6f94a23a4 | ||
|
|
50954e6a9a | ||
|
|
66b6f67835 | ||
|
|
1644401f8d | ||
|
|
1a326fc7fa | ||
|
|
a82096e68a | ||
|
|
90d3a94eb7 | ||
|
|
9dde5949a8 | ||
|
|
cff142b535 | ||
|
|
a4c5ac881a | ||
|
|
d35955ebf6 |
@@ -21,10 +21,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set Node.js 18.x
|
- name: Set Node.js 18.x
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18.x
|
node-version: 18.x
|
||||||
cache: npm
|
cache: npm
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 18
|
||||||
cache: npm
|
cache: npm
|
||||||
@@ -27,8 +27,8 @@ jobs:
|
|||||||
lint:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 18
|
||||||
cache: npm
|
cache: npm
|
||||||
|
|||||||
@@ -9,6 +9,6 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: Dependency Review
|
- name: Dependency Review
|
||||||
uses: actions/dependency-review-action@main
|
uses: actions/dependency-review-action@main
|
||||||
|
|||||||
+1
-1
@@ -79,7 +79,7 @@ Here are a few things you can do that will increase the likelihood of your pull
|
|||||||
|
|
||||||
- Write tests.
|
- Write tests.
|
||||||
- Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests.
|
- Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests.
|
||||||
- Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
|
- Write a [good commit message](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
|
||||||
|
|
||||||
## Cutting a new release
|
## Cutting a new release
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# dependency-review-action
|
# dependency-review-action
|
||||||
|
|
||||||
This action scans your pull requests for dependency changes, and will
|
This action scans your pull requests for dependency changes, and will
|
||||||
raise an error if any vulnerabilities or invalid licenses are being introduced. The action is supported by an [API endpoint](https://docs.github.com/en/rest/reference/dependency-graph#dependency-review) that diffs the dependencies between any two revisions on your default branch.
|
raise an error if any vulnerabilities or invalid licenses are being introduced. The action is supported by an [API endpoint](https://docs.github.com/en/rest/reference/dependency-graph#dependency-review) that diffs the dependencies between any two revisions on your default branch.
|
||||||
@@ -31,7 +31,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: 'Dependency Review'
|
- name: 'Dependency Review'
|
||||||
uses: actions/dependency-review-action@v3
|
uses: actions/dependency-review-action@v3
|
||||||
```
|
```
|
||||||
@@ -57,7 +57,7 @@ jobs:
|
|||||||
runs-on: self-hosted
|
runs-on: self-hosted
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: 'Dependency Review'
|
- name: 'Dependency Review'
|
||||||
uses: actions/dependency-review-action@v3
|
uses: actions/dependency-review-action@v3
|
||||||
```
|
```
|
||||||
@@ -66,20 +66,22 @@ jobs:
|
|||||||
|
|
||||||
Configure this action by either inlining these options in your workflow file, or by using an external configuration file. All configuration options are optional.
|
Configure this action by either inlining these options in your workflow file, or by using an external configuration file. All configuration options are optional.
|
||||||
|
|
||||||
| Option | Usage | Possible values | Default value |
|
| Option | Usage | Possible values | Default value |
|
||||||
|---------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|---------------|
|
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------- |
|
||||||
| `fail-on-severity` | Defines the threshold for the level of severity. The action will fail on any pull requests that introduce vulnerabilities of the specified severity level or higher. | `low`, `moderate`, `high`, `critical` | `low` |
|
| `fail-on-severity` | Defines the threshold for the level of severity. The action will fail on any pull requests that introduce vulnerabilities of the specified severity level or higher. | `low`, `moderate`, `high`, `critical` | `low` |
|
||||||
| `allow-licenses`\* | Contains a list of allowed licenses. The action will fail on pull requests that introduce dependencies with licenses that do not match the list. | Any [SPDX-compliant identifier(s)](https://spdx.org/licenses/) | none |
|
| `allow-licenses`\* | Contains a list of allowed licenses. The action will fail on pull requests that introduce dependencies with licenses that do not match the list. | Any [SPDX-compliant identifier(s)](https://spdx.org/licenses/) | none |
|
||||||
| `deny-licenses`\* | Contains a list of prohibited licenses. The action will fail on pull requests that introduce dependencies with licenses that match the list. | Any [SPDX-compliant identifier(s)](https://spdx.org/licenses/) | none |
|
| `deny-licenses`\* | Contains a list of prohibited licenses. The action will fail on pull requests that introduce dependencies with licenses that match the list. | Any [SPDX-compliant identifier(s)](https://spdx.org/licenses/) | none |
|
||||||
| `fail-on-scopes`† | Contains a list of strings of the build environments you want to support. The action will fail on pull requests that introduce vulnerabilities in the scopes that match the list. | `runtime`, `development`, `unknown` | `runtime` |
|
| `fail-on-scopes`† | Contains a list of strings of the build environments you want to support. The action will fail on pull requests that introduce vulnerabilities in the scopes that match the list. | `runtime`, `development`, `unknown` | `runtime` |
|
||||||
| `allow-ghsas` | Contains a list of GitHub Advisory Database IDs that can be skipped during detection. | Any GHSAs from the [GitHub Advisory Database](https://github.com/advisories) | none |
|
| `allow-ghsas` | Contains a list of GitHub Advisory Database IDs that can be skipped during detection. | Any GHSAs from the [GitHub Advisory Database](https://github.com/advisories) | none |
|
||||||
| `license-check` | Enable or disable the license check performed by the action. | `true`, `false` | `true` |
|
| `license-check` | Enable or disable the license check performed by the action. | `true`, `false` | `true` |
|
||||||
| `vulnerability-check` | Enable or disable the vulnerability check performed by the action. | `true`, `false` | `true` |
|
| `vulnerability-check` | Enable or disable the vulnerability check performed by the action. | `true`, `false` | `true` |
|
||||||
| `allow-dependencies-licenses`\* | Contains a list of packages that will be excluded from license checks. | Any package(s) in [purl](https://github.com/package-url/purl-spec) format | none |
|
| `allow-dependencies-licenses`\* | Contains a list of packages that will be excluded from license checks. | Any package(s) in [purl](https://github.com/package-url/purl-spec) format | none |
|
||||||
| `base-ref`/`head-ref` | Provide custom git references for the git base/head when performing the comparison check. This is only used for event types other than `pull_request` and `pull_request_target`. | Any valid git ref(s) in your project | none |
|
| `base-ref`/`head-ref` | Provide custom git references for the git base/head when performing the comparison check. This is only used for event types other than `pull_request` and `pull_request_target`. | Any valid git ref(s) in your project | none |
|
||||||
| `comment-summary-in-pr` | Enable or disable reporting the review summary as a comment in the pull request. If enabled, you must give the workflow or job permission `pull-requests: write`. | `true`, `false` | `false` |
|
| `comment-summary-in-pr` | Enable or disable reporting the review summary as a comment in the pull request. If enabled, you must give the workflow or job permission `pull-requests: write`. | `always`, `on-failure`, `never` | `never` |
|
||||||
| `deny-packages` | Any number of packages to block in a PR. | Package(s) in [purl](https://github.com/package-url/purl-spec) format | empty |
|
| `deny-packages` | Any number of packages to block in a PR. | Package(s) in [purl](https://github.com/package-url/purl-spec) format | empty |
|
||||||
| `deny-groups` | Any number of groups (namespaces) to block in a PR. | Namespace(s) in [purl](https://github.com/package-url/purl-spec) format (no package name, no version number) | empty |
|
| `deny-groups` | Any number of groups (namespaces) to block in a PR. | Namespace(s) in [purl](https://github.com/package-url/purl-spec) format (no package name, no version number) | empty |
|
||||||
|
| `retry-on-snapshot-warnings`\* | Enable or disable retrying the action every 10 seconds while waiting for dependency submission actions to complete. | `true`, `false` | `false` |
|
||||||
|
| `retry-on-snapshot-warnings-timeout`\* | Maximum amount of time (in seconds) to retry the action while waiting for dependency submission actions to complete. | Any positive integer | 120 |
|
||||||
|
|
||||||
\*not supported for use with GitHub Enterprise Server
|
\*not supported for use with GitHub Enterprise Server
|
||||||
|
|
||||||
@@ -101,7 +103,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: Dependency Review
|
- name: Dependency Review
|
||||||
uses: actions/dependency-review-action@v3
|
uses: actions/dependency-review-action@v3
|
||||||
with:
|
with:
|
||||||
@@ -126,7 +128,7 @@ Start by specifying that you will be using an external configuration file:
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Dependency Review
|
- name: Dependency Review
|
||||||
uses: actions/dependency-review-action@v2
|
uses: actions/dependency-review-action@v3
|
||||||
with:
|
with:
|
||||||
config-file: './.github/dependency-review-config.yml'
|
config-file: './.github/dependency-review-config.yml'
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -171,3 +171,29 @@ describe('licenses that are not valid SPDX licenses', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('it parses the comment-summary-in-pr input', async () => {
|
||||||
|
setInput('comment-summary-in-pr', 'true')
|
||||||
|
let config = await readConfig()
|
||||||
|
expect(config.comment_summary_in_pr).toBe('always')
|
||||||
|
|
||||||
|
clearInputs()
|
||||||
|
setInput('comment-summary-in-pr', 'false')
|
||||||
|
config = await readConfig()
|
||||||
|
expect(config.comment_summary_in_pr).toBe('never')
|
||||||
|
|
||||||
|
clearInputs()
|
||||||
|
setInput('comment-summary-in-pr', 'always')
|
||||||
|
config = await readConfig()
|
||||||
|
expect(config.comment_summary_in_pr).toBe('always')
|
||||||
|
|
||||||
|
clearInputs()
|
||||||
|
setInput('comment-summary-in-pr', 'never')
|
||||||
|
config = await readConfig()
|
||||||
|
expect(config.comment_summary_in_pr).toBe('never')
|
||||||
|
|
||||||
|
clearInputs()
|
||||||
|
setInput('comment-summary-in-pr', 'on-failure')
|
||||||
|
config = await readConfig()
|
||||||
|
expect(config.comment_summary_in_pr).toBe('on-failure')
|
||||||
|
})
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ const pipChange: Change = {
|
|||||||
ecosystem: 'pip',
|
ecosystem: 'pip',
|
||||||
name: 'package-1',
|
name: 'package-1',
|
||||||
version: '1.1.1',
|
version: '1.1.1',
|
||||||
package_url: 'pkg:pip/[email protected]',
|
package_url: 'pkg:pypi/[email protected]',
|
||||||
license: 'MIT',
|
license: 'MIT',
|
||||||
source_repository_url: 'github.com/some-repo',
|
source_repository_url: 'github.com/some-repo',
|
||||||
scope: 'runtime',
|
scope: 'runtime',
|
||||||
|
|||||||
+111
-17
@@ -19,7 +19,7 @@ const npmChange: Change = {
|
|||||||
vulnerabilities: [
|
vulnerabilities: [
|
||||||
{
|
{
|
||||||
severity: 'critical',
|
severity: 'critical',
|
||||||
advisory_ghsa_id: 'first-random_string',
|
advisory_ghsa_id: 'vulnerable-ghsa-id',
|
||||||
advisory_summary: 'very dangerous',
|
advisory_summary: 'very dangerous',
|
||||||
advisory_url: 'github.com/future-funk'
|
advisory_url: 'github.com/future-funk'
|
||||||
}
|
}
|
||||||
@@ -39,13 +39,13 @@ const rubyChange: Change = {
|
|||||||
vulnerabilities: [
|
vulnerabilities: [
|
||||||
{
|
{
|
||||||
severity: 'moderate',
|
severity: 'moderate',
|
||||||
advisory_ghsa_id: 'second-random_string',
|
advisory_ghsa_id: 'moderate-ghsa-id',
|
||||||
advisory_summary: 'not so dangerous',
|
advisory_summary: 'not so dangerous',
|
||||||
advisory_url: 'github.com/future-funk'
|
advisory_url: 'github.com/future-funk'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
severity: 'low',
|
severity: 'low',
|
||||||
advisory_ghsa_id: 'third-random_string',
|
advisory_ghsa_id: 'low-ghsa-id',
|
||||||
advisory_summary: 'dont page me',
|
advisory_summary: 'dont page me',
|
||||||
advisory_url: 'github.com/future-funk'
|
advisory_url: 'github.com/future-funk'
|
||||||
}
|
}
|
||||||
@@ -65,6 +65,64 @@ const noVulnNpmChange: Change = {
|
|||||||
vulnerabilities: []
|
vulnerabilities: []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const lodashChange: Change = {
|
||||||
|
change_type: 'added',
|
||||||
|
manifest: 'package.json',
|
||||||
|
ecosystem: 'npm',
|
||||||
|
name: 'lodash',
|
||||||
|
version: '4.17.0',
|
||||||
|
package_url: 'pkg:npm/[email protected]',
|
||||||
|
license: 'MIT',
|
||||||
|
source_repository_url: 'https://github.com/lodash/lodash',
|
||||||
|
scope: 'runtime',
|
||||||
|
vulnerabilities: [
|
||||||
|
{
|
||||||
|
severity: 'critical',
|
||||||
|
advisory_ghsa_id: 'GHSA-jf85-cpcp-j695',
|
||||||
|
advisory_summary: 'Prototype Pollution in lodash',
|
||||||
|
advisory_url: 'https://github.com/advisories/GHSA-jf85-cpcp-j695'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
severity: 'high',
|
||||||
|
advisory_ghsa_id: 'GHSA-4xc9-xhrj-v574',
|
||||||
|
advisory_summary: 'Prototype Pollution in lodash',
|
||||||
|
advisory_url: 'https://github.com/advisories/GHSA-4xc9-xhrj-v574'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
severity: 'high',
|
||||||
|
advisory_ghsa_id: 'GHSA-35jh-r3h4-6jhm',
|
||||||
|
advisory_summary: 'Command Injection in lodash',
|
||||||
|
advisory_url: 'https://github.com/advisories/GHSA-35jh-r3h4-6jhm'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
severity: 'high',
|
||||||
|
advisory_ghsa_id: 'GHSA-p6mc-m468-83gw',
|
||||||
|
advisory_summary: 'Prototype Pollution in lodash',
|
||||||
|
advisory_url: 'https://github.com/advisories/GHSA-p6mc-m468-83gw'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
severity: 'moderate',
|
||||||
|
advisory_ghsa_id: 'GHSA-x5rq-j2xg-h7qm',
|
||||||
|
advisory_summary:
|
||||||
|
'Regular Expression Denial of Service (ReDoS) in lodash',
|
||||||
|
advisory_url: 'https://github.com/advisories/GHSA-x5rq-j2xg-h7qm'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
severity: 'moderate',
|
||||||
|
advisory_ghsa_id: 'GHSA-29mw-wpgm-hmr9',
|
||||||
|
advisory_summary:
|
||||||
|
'Regular Expression Denial of Service (ReDoS) in lodash',
|
||||||
|
advisory_url: 'https://github.com/advisories/GHSA-29mw-wpgm-hmr9'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
severity: 'low',
|
||||||
|
advisory_ghsa_id: 'GHSA-fvqr-27wr-82fm',
|
||||||
|
advisory_summary: 'Prototype Pollution in lodash',
|
||||||
|
advisory_url: 'https://github.com/advisories/GHSA-fvqr-27wr-82fm'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
test('it properly filters changes by severity', async () => {
|
test('it properly filters changes by severity', async () => {
|
||||||
const changes = [npmChange, rubyChange]
|
const changes = [npmChange, rubyChange]
|
||||||
let result = filterChangesBySeverity('high', changes)
|
let result = filterChangesBySeverity('high', changes)
|
||||||
@@ -99,25 +157,61 @@ test('it properly handles undefined advisory IDs', async () => {
|
|||||||
test('it properly filters changes with allowed vulnerabilities', async () => {
|
test('it properly filters changes with allowed vulnerabilities', async () => {
|
||||||
const changes = [npmChange, rubyChange, noVulnNpmChange]
|
const changes = [npmChange, rubyChange, noVulnNpmChange]
|
||||||
|
|
||||||
let result = filterAllowedAdvisories(['notrealGHSAID'], changes)
|
const fakeGHSAChanges = filterAllowedAdvisories(['notrealGHSAID'], changes)
|
||||||
expect(result).toEqual([npmChange, rubyChange, noVulnNpmChange])
|
expect(fakeGHSAChanges).toEqual([npmChange, rubyChange, noVulnNpmChange])
|
||||||
|
})
|
||||||
|
|
||||||
result = filterAllowedAdvisories(['first-random_string'], changes)
|
test('it properly filters only allowed vulnerabilities', async () => {
|
||||||
expect(result).toEqual([rubyChange, noVulnNpmChange])
|
const changes = [npmChange, rubyChange, noVulnNpmChange]
|
||||||
|
const oldVulns = [
|
||||||
|
...npmChange.vulnerabilities,
|
||||||
|
...rubyChange.vulnerabilities,
|
||||||
|
...noVulnNpmChange.vulnerabilities
|
||||||
|
]
|
||||||
|
|
||||||
result = filterAllowedAdvisories(
|
const vulnerable = filterAllowedAdvisories(['vulnerable-ghsa-id'], changes)
|
||||||
['second-random_string', 'third-random_string'],
|
|
||||||
|
const newVulns = vulnerable.map(change => change.vulnerabilities).flat()
|
||||||
|
|
||||||
|
expect(newVulns.length).toEqual(oldVulns.length - 1)
|
||||||
|
expect(newVulns).not.toContainEqual(
|
||||||
|
expect.objectContaining({advisory_ghsa_id: 'vulnerable-ghsa-id'})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('does not drop dependencies when filtering by GHSA', async () => {
|
||||||
|
const changes = [npmChange, rubyChange, noVulnNpmChange]
|
||||||
|
const result = filterAllowedAdvisories(
|
||||||
|
['moderate-ghsa-id', 'low-ghsa-id', 'GHSA-jf85-cpcp-j695'],
|
||||||
changes
|
changes
|
||||||
)
|
)
|
||||||
expect(result).toEqual([npmChange, noVulnNpmChange])
|
|
||||||
|
|
||||||
result = filterAllowedAdvisories(
|
expect(result.map(change => change.name)).toEqual(
|
||||||
['first-random_string', 'second-random_string', 'third-random_string'],
|
changes.map(change => change.name)
|
||||||
changes
|
|
||||||
)
|
)
|
||||||
expect(result).toEqual([noVulnNpmChange])
|
})
|
||||||
|
|
||||||
// if we have a change with multiple vulnerabilities but only one is allowed, we still should not filter out that change
|
test('it properly filters multiple GHSAs', async () => {
|
||||||
result = filterAllowedAdvisories(['second-random_string'], changes)
|
const allowedGHSAs = ['vulnerable-ghsa-id', 'moderate-ghsa-id', 'low-ghsa-id']
|
||||||
expect(result).toEqual([npmChange, rubyChange, noVulnNpmChange])
|
const changes = [npmChange, rubyChange, noVulnNpmChange]
|
||||||
|
const oldVulns = changes.map(change => change.vulnerabilities).flat()
|
||||||
|
|
||||||
|
const result = filterAllowedAdvisories(allowedGHSAs, changes)
|
||||||
|
|
||||||
|
const newVulns = result.map(change => change.vulnerabilities).flat()
|
||||||
|
|
||||||
|
expect(newVulns.length).toEqual(oldVulns.length - 3)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('it filters out GHSA dependencies', async () => {
|
||||||
|
const lodash = filterAllowedAdvisories(
|
||||||
|
['GHSA-jf85-cpcp-j695'],
|
||||||
|
[lodashChange]
|
||||||
|
)[0]
|
||||||
|
// the filter should have removed a single GHSA from the list
|
||||||
|
const expected = lodashChange.vulnerabilities.filter(
|
||||||
|
vuln => vuln.advisory_ghsa_id !== 'GHSA-jf85-cpcp-j695'
|
||||||
|
)
|
||||||
|
expect(expected.length).toEqual(lodashChange.vulnerabilities.length - 1)
|
||||||
|
expect(lodash.vulnerabilities).toEqual(expected)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ const pipChange: Change = {
|
|||||||
ecosystem: 'pip',
|
ecosystem: 'pip',
|
||||||
name: 'package-1',
|
name: 'package-1',
|
||||||
version: '1.1.1',
|
version: '1.1.1',
|
||||||
package_url: 'pkg:pip/[email protected]',
|
package_url: 'pkg:pypi/[email protected]',
|
||||||
license: 'MIT',
|
license: 'MIT',
|
||||||
source_repository_url: 'github.com/some-repo',
|
source_repository_url: 'github.com/some-repo',
|
||||||
scope: 'runtime',
|
scope: 'runtime',
|
||||||
@@ -183,7 +183,7 @@ test('it does not filter out changes that are on the exclusions list', async ()
|
|||||||
const changes: Changes = [pipChange, npmChange, rubyChange]
|
const changes: Changes = [pipChange, npmChange, rubyChange]
|
||||||
const licensesConfig = {
|
const licensesConfig = {
|
||||||
allow: ['BSD'],
|
allow: ['BSD'],
|
||||||
licenseExclusions: ['pkg:pip/[email protected]', 'pkg:npm/[email protected]']
|
licenseExclusions: ['pkg:pypi/[email protected]', 'pkg:npm/[email protected]']
|
||||||
}
|
}
|
||||||
const invalidLicenses = await getInvalidLicenseChanges(
|
const invalidLicenses = await getInvalidLicenseChanges(
|
||||||
changes,
|
changes,
|
||||||
@@ -199,7 +199,7 @@ test('it does not fail when the packages dont have a valid PURL', async () => {
|
|||||||
const changes: Changes = [emptyPurlChange, npmChange, rubyChange]
|
const changes: Changes = [emptyPurlChange, npmChange, rubyChange]
|
||||||
const licensesConfig = {
|
const licensesConfig = {
|
||||||
allow: ['BSD'],
|
allow: ['BSD'],
|
||||||
licenseExclusions: ['pkg:pip/[email protected]', 'pkg:npm/[email protected]']
|
licenseExclusions: ['pkg:pypi/[email protected]', 'pkg:npm/[email protected]']
|
||||||
}
|
}
|
||||||
|
|
||||||
const invalidLicenses = await getInvalidLicenseChanges(
|
const invalidLicenses = await getInvalidLicenseChanges(
|
||||||
@@ -213,7 +213,10 @@ test('it does filters out changes if they are not on the exclusions list', async
|
|||||||
const changes: Changes = [pipChange, npmChange, rubyChange]
|
const changes: Changes = [pipChange, npmChange, rubyChange]
|
||||||
const licensesConfig = {
|
const licensesConfig = {
|
||||||
allow: ['BSD'],
|
allow: ['BSD'],
|
||||||
licenseExclusions: ['pkg:pip/[email protected]', 'pkg:npm/[email protected]']
|
licenseExclusions: [
|
||||||
|
'pkg:pypi/[email protected]',
|
||||||
|
'pkg:npm/[email protected]'
|
||||||
|
]
|
||||||
}
|
}
|
||||||
const invalidLicenses = await getInvalidLicenseChanges(
|
const invalidLicenses = await getInvalidLicenseChanges(
|
||||||
changes,
|
changes,
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ const defaultConfig: ConfigurationOptions = {
|
|||||||
deny_licenses: [],
|
deny_licenses: [],
|
||||||
deny_packages: [],
|
deny_packages: [],
|
||||||
deny_groups: [],
|
deny_groups: [],
|
||||||
comment_summary_in_pr: true
|
comment_summary_in_pr: true,
|
||||||
|
retry_on_snapshot_warnings: false,
|
||||||
|
retry_on_snapshot_warnings_timeout: 120
|
||||||
}
|
}
|
||||||
|
|
||||||
const changesWithEmptyManifests: Changes = [
|
const changesWithEmptyManifests: Changes = [
|
||||||
|
|||||||
+12
-4
@@ -30,7 +30,7 @@ inputs:
|
|||||||
description: Comma-separated list of forbidden licenses (e.g. "MIT, GPL 3.0, BSD 2 Clause")
|
description: Comma-separated list of forbidden licenses (e.g. "MIT, GPL 3.0, BSD 2 Clause")
|
||||||
required: false
|
required: false
|
||||||
allow-dependencies-licenses:
|
allow-dependencies-licenses:
|
||||||
description: Comma-separated list of dependencies in purl format (e.g. "pkg:npm/express, pkg:pip/pycrypto"). These dependencies will be permitted to use any license, no matter what license policy is enforced otherwise.
|
description: Comma-separated list of dependencies in purl format (e.g. "pkg:npm/express, pkg:pypi/pycrypto"). These dependencies will be permitted to use any license, no matter what license policy is enforced otherwise.
|
||||||
required: false
|
required: false
|
||||||
allow-ghsas:
|
allow-ghsas:
|
||||||
description: Comma-separated list of allowed GitHub Advisory IDs (e.g. "GHSA-abcd-1234-5679, GHSA-efgh-1234-5679")
|
description: Comma-separated list of allowed GitHub Advisory IDs (e.g. "GHSA-abcd-1234-5679, GHSA-efgh-1234-5679")
|
||||||
@@ -45,14 +45,22 @@ inputs:
|
|||||||
description: A boolean to determine if vulnerability checks should be performed
|
description: A boolean to determine if vulnerability checks should be performed
|
||||||
required: false
|
required: false
|
||||||
comment-summary-in-pr:
|
comment-summary-in-pr:
|
||||||
description: A boolean to determine if the report should be posted as a comment in the PR itself. Setting this to true requires you to give the workflow the write permissions for pull-requests
|
description: Determines if the summary is posted as a comment in the PR itself. Setting this to `always` or `on-failure` requires you to give the workflow the write permissions for pull-requests
|
||||||
required: false
|
required: false
|
||||||
deny-packages:
|
deny-packages:
|
||||||
description: A comma-separated list of package URLs to deny (e.g. "pkg:npm/express, pkg:pip/pycrypto")
|
description: A comma-separated list of package URLs to deny (e.g. "pkg:npm/express, pkg:pypi/pycrypto")
|
||||||
required: false
|
required: false
|
||||||
deny-groups:
|
deny-groups:
|
||||||
description: A comma-separated list of package URLs for group(s)/namespace(s) to deny (e.g. "pkg:npm/express, pkg:pip/pycrypto")
|
description: A comma-separated list of package URLs for group(s)/namespace(s) to deny (e.g. "pkg:npm/express, pkg:pypi/pycrypto")
|
||||||
required: false
|
required: false
|
||||||
|
retry-on-snapshot-warnings:
|
||||||
|
description: Whether to retry on snapshot warnings
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
retry-on-snapshot-warnings-timeout:
|
||||||
|
description: Number of seconds to wait before stopping snapshot retries.
|
||||||
|
required: false
|
||||||
|
default: 120
|
||||||
runs:
|
runs:
|
||||||
using: 'node16'
|
using: 'node16'
|
||||||
main: 'dist/index.js'
|
main: 'dist/index.js'
|
||||||
|
|||||||
+27450
-19507
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+280
-2
@@ -47,6 +47,28 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|||||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
@fastify/busboy
|
||||||
|
MIT
|
||||||
|
Copyright Brian White. All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
@octokit/app
|
@octokit/app
|
||||||
MIT
|
MIT
|
||||||
The MIT License
|
The MIT License
|
||||||
@@ -1175,9 +1197,240 @@ FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TOR
|
|||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
lodash
|
lodash.includes
|
||||||
MIT
|
MIT
|
||||||
Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
Copyright jQuery Foundation and other contributors <https://jquery.org/>
|
||||||
|
|
||||||
|
Based on Underscore.js, copyright Jeremy Ashkenas,
|
||||||
|
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
|
||||||
|
|
||||||
|
This software consists of voluntary contributions made by many
|
||||||
|
individuals. For exact contribution history, see the revision history
|
||||||
|
available at https://github.com/lodash/lodash
|
||||||
|
|
||||||
|
The following license applies to all parts of this software except as
|
||||||
|
documented below:
|
||||||
|
|
||||||
|
====
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
====
|
||||||
|
|
||||||
|
Copyright and related rights for sample code are waived via CC0. Sample
|
||||||
|
code is defined as all source code displayed within the prose of the
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
CC0: http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
|
||||||
|
====
|
||||||
|
|
||||||
|
Files located in the node_modules and vendor directories are externally
|
||||||
|
maintained libraries used by this software which have their own
|
||||||
|
licenses; we recommend you read them, as their terms may differ from the
|
||||||
|
terms above.
|
||||||
|
|
||||||
|
|
||||||
|
lodash.isboolean
|
||||||
|
MIT
|
||||||
|
Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
|
||||||
|
Based on Underscore.js, copyright 2009-2016 Jeremy Ashkenas,
|
||||||
|
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
lodash.isinteger
|
||||||
|
MIT
|
||||||
|
Copyright jQuery Foundation and other contributors <https://jquery.org/>
|
||||||
|
|
||||||
|
Based on Underscore.js, copyright Jeremy Ashkenas,
|
||||||
|
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
|
||||||
|
|
||||||
|
This software consists of voluntary contributions made by many
|
||||||
|
individuals. For exact contribution history, see the revision history
|
||||||
|
available at https://github.com/lodash/lodash
|
||||||
|
|
||||||
|
The following license applies to all parts of this software except as
|
||||||
|
documented below:
|
||||||
|
|
||||||
|
====
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
====
|
||||||
|
|
||||||
|
Copyright and related rights for sample code are waived via CC0. Sample
|
||||||
|
code is defined as all source code displayed within the prose of the
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
CC0: http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
|
||||||
|
====
|
||||||
|
|
||||||
|
Files located in the node_modules and vendor directories are externally
|
||||||
|
maintained libraries used by this software which have their own
|
||||||
|
licenses; we recommend you read them, as their terms may differ from the
|
||||||
|
terms above.
|
||||||
|
|
||||||
|
|
||||||
|
lodash.isnumber
|
||||||
|
MIT
|
||||||
|
Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
|
||||||
|
Based on Underscore.js, copyright 2009-2016 Jeremy Ashkenas,
|
||||||
|
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
lodash.isplainobject
|
||||||
|
MIT
|
||||||
|
Copyright jQuery Foundation and other contributors <https://jquery.org/>
|
||||||
|
|
||||||
|
Based on Underscore.js, copyright Jeremy Ashkenas,
|
||||||
|
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
|
||||||
|
|
||||||
|
This software consists of voluntary contributions made by many
|
||||||
|
individuals. For exact contribution history, see the revision history
|
||||||
|
available at https://github.com/lodash/lodash
|
||||||
|
|
||||||
|
The following license applies to all parts of this software except as
|
||||||
|
documented below:
|
||||||
|
|
||||||
|
====
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
====
|
||||||
|
|
||||||
|
Copyright and related rights for sample code are waived via CC0. Sample
|
||||||
|
code is defined as all source code displayed within the prose of the
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
CC0: http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
|
||||||
|
====
|
||||||
|
|
||||||
|
Files located in the node_modules and vendor directories are externally
|
||||||
|
maintained libraries used by this software which have their own
|
||||||
|
licenses; we recommend you read them, as their terms may differ from the
|
||||||
|
terms above.
|
||||||
|
|
||||||
|
|
||||||
|
lodash.isstring
|
||||||
|
MIT
|
||||||
|
Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
|
||||||
|
Based on Underscore.js, copyright 2009-2016 Jeremy Ashkenas,
|
||||||
|
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
lodash.once
|
||||||
|
MIT
|
||||||
|
Copyright jQuery Foundation and other contributors <https://jquery.org/>
|
||||||
|
|
||||||
Based on Underscore.js, copyright Jeremy Ashkenas,
|
Based on Underscore.js, copyright Jeremy Ashkenas,
|
||||||
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
|
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
|
||||||
@@ -1517,6 +1770,31 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
undici
|
||||||
|
MIT
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) Matteo Collina and Undici contributors
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
universal-github-app-jwt
|
universal-github-app-jwt
|
||||||
MIT
|
MIT
|
||||||
The MIT License
|
The MIT License
|
||||||
|
|||||||
+53
-17
@@ -18,7 +18,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: 'Dependency Review'
|
- name: 'Dependency Review'
|
||||||
uses: actions/dependency-review-action@v3
|
uses: actions/dependency-review-action@v3
|
||||||
```
|
```
|
||||||
@@ -39,7 +39,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: 'Dependency Review'
|
- name: 'Dependency Review'
|
||||||
uses: actions/dependency-review-action@v3
|
uses: actions/dependency-review-action@v3
|
||||||
with:
|
with:
|
||||||
@@ -76,14 +76,14 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: 'Dependency Review'
|
- name: 'Dependency Review'
|
||||||
uses: actions/dependency-review-action@v3
|
uses: actions/dependency-review-action@v3
|
||||||
with:
|
with:
|
||||||
config-file: './.github/dependency-review-config.yml'
|
config-file: './.github/dependency-review-config.yml'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Using a configuration file from a external repository
|
## Using a configuration file from an external repository
|
||||||
|
|
||||||
The following example will use a configuration file from an external public GitHub repository to configure the action.
|
The following example will use a configuration file from an external public GitHub repository to configure the action.
|
||||||
|
|
||||||
@@ -103,14 +103,14 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: 'Dependency Review'
|
- name: 'Dependency Review'
|
||||||
uses: actions/dependency-review-action@v3
|
uses: actions/dependency-review-action@v3
|
||||||
with:
|
with:
|
||||||
config-file: 'github/octorepo/dependency-review-config.yml@main'
|
config-file: 'github/octorepo/dependency-review-config.yml@main'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Using a configuration file from a external repository with a personal access token
|
## Using a configuration file from an external repository with a personal access token
|
||||||
|
|
||||||
The following example will use a configuration file from an external private GtiHub repository to configure the action.
|
The following example will use a configuration file from an external private GtiHub repository to configure the action.
|
||||||
|
|
||||||
@@ -130,12 +130,12 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: 'Dependency Review'
|
- name: 'Dependency Review'
|
||||||
uses: actions/dependency-review-action@v3
|
uses: actions/dependency-review-action@v3
|
||||||
with:
|
with:
|
||||||
config-file: 'github/octorepo-private/dependency-review-config.yml@main'
|
config-file: 'github/octorepo-private/dependency-review-config.yml@main'
|
||||||
config-file-token: ${{ secrets.GITHUB_TOKEN }} # or a personal access token
|
external-repo-token: ${{ secrets.GITHUB_TOKEN }} # or a personal access token
|
||||||
```
|
```
|
||||||
|
|
||||||
## Getting the results of the action in the PR as a comment
|
## Getting the results of the action in the PR as a comment
|
||||||
@@ -155,13 +155,13 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: 'Dependency Review'
|
- name: 'Dependency Review'
|
||||||
uses: actions/dependency-review-action@v3
|
uses: actions/dependency-review-action@v3
|
||||||
with:
|
with:
|
||||||
fail-on-severity: critical
|
fail-on-severity: critical
|
||||||
deny-licenses: LGPL-2.0, BSD-2-Clause
|
deny-licenses: LGPL-2.0, BSD-2-Clause
|
||||||
comment-summary-in-pr: true
|
comment-summary-in-pr: always
|
||||||
```
|
```
|
||||||
|
|
||||||
## Exclude dependencies from the license check
|
## Exclude dependencies from the license check
|
||||||
@@ -183,14 +183,14 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: 'Dependency Review'
|
- name: 'Dependency Review'
|
||||||
uses: actions/dependency-review-action@v3
|
uses: actions/dependency-review-action@v3
|
||||||
with:
|
with:
|
||||||
fail-on-severity: critical
|
fail-on-severity: critical
|
||||||
deny-licenses: LGPL-2.0, BSD-2-Clause
|
deny-licenses: LGPL-2.0, BSD-2-Clause
|
||||||
comment-summary-in-pr: true
|
comment-summary-in-pr: always
|
||||||
allow-dependencies-licenses: 'pkg:npm/loadash, pkg:pip/requests'
|
allow-dependencies-licenses: 'pkg:npm/loadash, pkg:pypi/requests'
|
||||||
```
|
```
|
||||||
|
|
||||||
If we were to use configuration file, the configuration would look like this:
|
If we were to use configuration file, the configuration would look like this:
|
||||||
@@ -202,7 +202,7 @@ allow-licenses:
|
|||||||
- 'BSD-2-Clause'
|
- 'BSD-2-Clause'
|
||||||
allow-dependencies-licenses:
|
allow-dependencies-licenses:
|
||||||
- 'pkg:npm/loadash'
|
- 'pkg:npm/loadash'
|
||||||
- 'pkg:pip/requests'
|
- 'pkg:pypi/requests'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Only check for vulnerabilities
|
## Only check for vulnerabilities
|
||||||
@@ -222,12 +222,12 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: 'Dependency Review'
|
- name: 'Dependency Review'
|
||||||
uses: actions/dependency-review-action@v3
|
uses: actions/dependency-review-action@v3
|
||||||
with:
|
with:
|
||||||
fail-on-severity: critical
|
fail-on-severity: critical
|
||||||
comment-summary-in-pr: true
|
comment-summary-in-pr: always
|
||||||
license-check: false
|
license-check: false
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -251,10 +251,46 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: 'Dependency Review'
|
- name: 'Dependency Review'
|
||||||
uses: actions/dependency-review-action@v3
|
uses: actions/dependency-review-action@v3
|
||||||
with:
|
with:
|
||||||
deny-packages: 'pkg:maven/org.apache.logging.log4j/log4j-api,pkg:maven/org.apache.logging.log4j/log4j-core'
|
deny-packages: 'pkg:maven/org.apache.logging.log4j/log4j-api,pkg:maven/org.apache.logging.log4j/log4j-core'
|
||||||
deny-groups: 'pkg:maven/com.bazaarvoice.jolt'
|
deny-groups: 'pkg:maven/com.bazaarvoice.jolt'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Waiting for dependency submission jobs to complete
|
||||||
|
|
||||||
|
When possible, this action will [include dependencies submitted through the dependency submission API][DSAPI]. In this case,
|
||||||
|
it's important for the action not to complete until all of the relevant dependencies have been submitted for both the base
|
||||||
|
and head commits.
|
||||||
|
|
||||||
|
When this action runs before one or more of the dependency submission actions, there will be an unequal number of dependency
|
||||||
|
snapshots between the base and head commits. For example, there may be one snapshot available for the tip of `main` and none
|
||||||
|
for the PR branch. In that case, the API response will contain a "snapshot warning" explaining the discrepancy.
|
||||||
|
|
||||||
|
In this example, when the action encounters one of these warnings it will retry every 10 seconds after that for 60 seconds
|
||||||
|
or until there is no warning in the response.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: 'Dependency Review'
|
||||||
|
on: [pull_request]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
dependency-review:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: 'Checkout Repository'
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: 'Dependency Review'
|
||||||
|
uses: actions/dependency-review-action@v3
|
||||||
|
with:
|
||||||
|
retry-on-snapshot-warnings: true
|
||||||
|
retry-on-snapshot-warnings-timeout: 60
|
||||||
|
```
|
||||||
|
|
||||||
|
[DSAPI]: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#best-practices-for-using-the-dependency-review-api-and-the-dependency-submission-api-together
|
||||||
|
|||||||
Generated
+1845
-2188
File diff suppressed because it is too large
Load Diff
+22
-22
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "dependency-review-action",
|
"name": "dependency-review-action",
|
||||||
"version": "3.0.7",
|
"version": "3.1.4",
|
||||||
"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",
|
||||||
@@ -25,37 +25,37 @@
|
|||||||
"author": "GitHub",
|
"author": "GitHub",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.10.0",
|
"@actions/core": "^1.10.1",
|
||||||
"@actions/github": "^5.1.1",
|
"@actions/github": "^5.1.1",
|
||||||
"@octokit/plugin-retry": "^5.0.4",
|
"@octokit/plugin-retry": "^5.0.4",
|
||||||
"@octokit/request-error": "^2.1.0",
|
"@octokit/request-error": "^2.1.0",
|
||||||
|
"@types/jest": "^29.5.11",
|
||||||
"ansi-styles": "^6.2.1",
|
"ansi-styles": "^6.2.1",
|
||||||
"got": "^13.0.0",
|
"got": "^13.0.0",
|
||||||
|
"jest": "^29.7.0",
|
||||||
"octokit": "^2.1.0",
|
"octokit": "^2.1.0",
|
||||||
"packageurl-js": "^1.0.2",
|
"packageurl-js": "^1.2.0",
|
||||||
"spdx-expression-parse": "^3.0.1",
|
"spdx-expression-parse": "^3.0.1",
|
||||||
"spdx-satisfies": "^5.0.1",
|
"spdx-satisfies": "^5.0.1",
|
||||||
"yaml": "^2.3.1",
|
"ts-jest": "^29.1.1",
|
||||||
"zod": "^3.21.4"
|
"yaml": "^2.3.4",
|
||||||
|
"zod": "^3.22.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^27.5.2",
|
"@types/node": "^16.18.62",
|
||||||
"@types/node": "^16.18.38",
|
"@types/spdx-expression-parse": "^3.0.4",
|
||||||
"@types/spdx-expression-parse": "^3.0.2",
|
"@types/spdx-satisfies": "^0.1.1",
|
||||||
"@types/spdx-satisfies": "^0.1.0",
|
"@typescript-eslint/eslint-plugin": "^6.15.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.2.0",
|
"@typescript-eslint/parser": "^6.16.0",
|
||||||
"@typescript-eslint/parser": "^6.2.1",
|
"@vercel/ncc": "^0.38.0",
|
||||||
"@vercel/ncc": "^0.36.1",
|
"esbuild-register": "^3.5.0",
|
||||||
"esbuild-register": "^3.4.2",
|
"eslint": "^8.56.0",
|
||||||
"eslint": "^8.44.0",
|
"eslint-plugin-github": "^4.10.1",
|
||||||
"eslint-plugin-github": "^4.8.0",
|
"eslint-plugin-jest": "^27.6.0",
|
||||||
"eslint-plugin-jest": "^27.2.2",
|
"eslint-plugin-prettier": "^5.0.1",
|
||||||
"eslint-plugin-prettier": "^5.0.0",
|
|
||||||
"jest": "^27.5.1",
|
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"nodemon": "^3.0.1",
|
"nodemon": "^3.0.2",
|
||||||
"prettier": "3.0.1",
|
"prettier": "3.1.1",
|
||||||
"ts-jest": "^27.1.4",
|
"typescript": "^5.3.2"
|
||||||
"typescript": "^4.9.5"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,11 +26,13 @@ const defaultConfig: ConfigurationOptions = {
|
|||||||
deny_groups: [],
|
deny_groups: [],
|
||||||
allow_dependencies_licenses: [
|
allow_dependencies_licenses: [
|
||||||
'pkg:npm/[email protected]',
|
'pkg:npm/[email protected]',
|
||||||
'pkg:pip/requests',
|
'pkg:pypi/requests',
|
||||||
'pkg:pip/certifi',
|
'pkg:pypi/certifi',
|
||||||
'pkg:pip/[email protected]'
|
'pkg:pypi/[email protected]'
|
||||||
],
|
],
|
||||||
comment_summary_in_pr: true
|
comment_summary_in_pr: true,
|
||||||
|
retry_on_snapshot_warnings: false,
|
||||||
|
retry_on_snapshot_warnings_timeout: 120
|
||||||
}
|
}
|
||||||
|
|
||||||
const tmpDir = path.resolve(__dirname, '../tmp')
|
const tmpDir = path.resolve(__dirname, '../tmp')
|
||||||
|
|||||||
+16
-2
@@ -40,7 +40,13 @@ function readInlineConfig(): ConfigurationOptionsPartial {
|
|||||||
const vulnerability_check = getOptionalBoolean('vulnerability-check')
|
const vulnerability_check = getOptionalBoolean('vulnerability-check')
|
||||||
const base_ref = getOptionalInput('base-ref')
|
const base_ref = getOptionalInput('base-ref')
|
||||||
const head_ref = getOptionalInput('head-ref')
|
const head_ref = getOptionalInput('head-ref')
|
||||||
const comment_summary_in_pr = getOptionalBoolean('comment-summary-in-pr')
|
const comment_summary_in_pr = getOptionalInput('comment-summary-in-pr')
|
||||||
|
const retry_on_snapshot_warnings = getOptionalBoolean(
|
||||||
|
'retry-on-snapshot-warnings'
|
||||||
|
)
|
||||||
|
const retry_on_snapshot_warnings_timeout = getOptionalNumber(
|
||||||
|
'retry-on-snapshot-warnings-timeout'
|
||||||
|
)
|
||||||
|
|
||||||
validatePURL(allow_dependencies_licenses)
|
validatePURL(allow_dependencies_licenses)
|
||||||
validateLicenses('allow-licenses', allow_licenses)
|
validateLicenses('allow-licenses', allow_licenses)
|
||||||
@@ -59,7 +65,9 @@ function readInlineConfig(): ConfigurationOptionsPartial {
|
|||||||
vulnerability_check,
|
vulnerability_check,
|
||||||
base_ref,
|
base_ref,
|
||||||
head_ref,
|
head_ref,
|
||||||
comment_summary_in_pr
|
comment_summary_in_pr,
|
||||||
|
retry_on_snapshot_warnings,
|
||||||
|
retry_on_snapshot_warnings_timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
return Object.fromEntries(
|
return Object.fromEntries(
|
||||||
@@ -67,6 +75,12 @@ function readInlineConfig(): ConfigurationOptionsPartial {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getOptionalNumber(name: string): number | undefined {
|
||||||
|
const value = core.getInput(name)
|
||||||
|
const parsed = z.string().regex(/^\d+$/).transform(Number).safeParse(value)
|
||||||
|
return parsed.success ? parsed.data : undefined
|
||||||
|
}
|
||||||
|
|
||||||
function getOptionalBoolean(name: string): boolean | undefined {
|
function getOptionalBoolean(name: string): boolean | undefined {
|
||||||
const value = core.getInput(name)
|
const value = core.getInput(name)
|
||||||
return value.length > 0 ? core.getBooleanInput(name) : undefined
|
return value.length > 0 ? core.getBooleanInput(name) : undefined
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ export async function compare({
|
|||||||
url: '/repos/{owner}/{repo}/dependency-graph/compare/{basehead}',
|
url: '/repos/{owner}/{repo}/dependency-graph/compare/{basehead}',
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
basehead: `${baseRef}...${headRef}`
|
basehead: `${baseRef}...${headRef}`,
|
||||||
|
per_page: 5
|
||||||
},
|
},
|
||||||
response => {
|
response => {
|
||||||
if (
|
if (
|
||||||
|
|||||||
+23
-13
@@ -1,5 +1,13 @@
|
|||||||
import {Changes, Severity, SEVERITIES, Scope} from './schemas'
|
import {Changes, Severity, SEVERITIES, Scope} from './schemas'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters changes by a severity level. Only vulnerable
|
||||||
|
* dependencies will be returned.
|
||||||
|
*
|
||||||
|
* @param severity - The severity level to filter by.
|
||||||
|
* @param changes - The array of changes to filter.
|
||||||
|
* @returns The filtered array of changes that match the specified severity level and have vulnerabilities.
|
||||||
|
*/
|
||||||
export function filterChangesBySeverity(
|
export function filterChangesBySeverity(
|
||||||
severity: Severity,
|
severity: Severity,
|
||||||
changes: Changes
|
changes: Changes
|
||||||
@@ -31,7 +39,14 @@ export function filterChangesBySeverity(
|
|||||||
filteredChanges = filteredChanges.filter(
|
filteredChanges = filteredChanges.filter(
|
||||||
change => change.vulnerabilities.length > 0
|
change => change.vulnerabilities.length > 0
|
||||||
)
|
)
|
||||||
return filteredChanges
|
|
||||||
|
// only report vulnerability additions
|
||||||
|
return filteredChanges.filter(
|
||||||
|
change =>
|
||||||
|
change.change_type === 'added' &&
|
||||||
|
change.vulnerabilities !== undefined &&
|
||||||
|
change.vulnerabilities.length > 0
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function filterChangesByScopes(
|
export function filterChangesByScopes(
|
||||||
@@ -67,25 +82,20 @@ export function filterAllowedAdvisories(
|
|||||||
return changes
|
return changes
|
||||||
}
|
}
|
||||||
|
|
||||||
const filteredChanges = changes.filter(change => {
|
const filteredChanges = changes.map(change => {
|
||||||
const noAdvisories =
|
const noAdvisories =
|
||||||
change.vulnerabilities === undefined ||
|
change.vulnerabilities === undefined ||
|
||||||
change.vulnerabilities.length === 0
|
change.vulnerabilities.length === 0
|
||||||
|
|
||||||
if (noAdvisories) {
|
if (noAdvisories) {
|
||||||
return true
|
return change
|
||||||
}
|
}
|
||||||
|
const newChange = {...change}
|
||||||
|
newChange.vulnerabilities = change.vulnerabilities.filter(
|
||||||
|
vuln => !ghsas.includes(vuln.advisory_ghsa_id)
|
||||||
|
)
|
||||||
|
|
||||||
let allAllowedAdvisories = true
|
return newChange
|
||||||
// if there's at least one advisory that is not allowlisted, we will keep the change
|
|
||||||
for (const vulnerability of change.vulnerabilities) {
|
|
||||||
if (!ghsas.includes(vulnerability.advisory_ghsa_id)) {
|
|
||||||
allAllowedAdvisories = false
|
|
||||||
}
|
|
||||||
if (!allAllowedAdvisories) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return filteredChanges
|
return filteredChanges
|
||||||
|
|||||||
+4
-2
@@ -32,7 +32,7 @@ export async function getInvalidLicenseChanges(
|
|||||||
const {allow, deny} = licenses
|
const {allow, deny} = licenses
|
||||||
const licenseExclusions = licenses.licenseExclusions?.map(
|
const licenseExclusions = licenses.licenseExclusions?.map(
|
||||||
(pkgUrl: string) => {
|
(pkgUrl: string) => {
|
||||||
return PackageURL.fromString(pkgUrl)
|
return PackageURL.fromString(encodeURI(pkgUrl))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -45,7 +45,9 @@ export async function getInvalidLicenseChanges(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
const changeAsPackageURL = PackageURL.fromString(change.package_url)
|
const changeAsPackageURL = PackageURL.fromString(
|
||||||
|
encodeURI(change.package_url)
|
||||||
|
)
|
||||||
|
|
||||||
// We want to find if the licenseExclussion list contains the PackageURL of the Change
|
// 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 does, we want to filter it out and therefore return false
|
||||||
|
|||||||
+56
-14
@@ -18,18 +18,60 @@ import {groupDependenciesByManifest} from './utils'
|
|||||||
import {commentPr} from './comment-pr'
|
import {commentPr} from './comment-pr'
|
||||||
import {getDeniedChanges} from './deny'
|
import {getDeniedChanges} from './deny'
|
||||||
|
|
||||||
|
async function delay(ms: number): Promise<void> {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, ms))
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getComparison(
|
||||||
|
baseRef: string,
|
||||||
|
headRef: string,
|
||||||
|
retryOpts?: {
|
||||||
|
retryUntil: number
|
||||||
|
retryDelay: number
|
||||||
|
}
|
||||||
|
): ReturnType<typeof dependencyGraph.compare> {
|
||||||
|
const comparison = await dependencyGraph.compare({
|
||||||
|
owner: github.context.repo.owner,
|
||||||
|
repo: github.context.repo.repo,
|
||||||
|
baseRef,
|
||||||
|
headRef
|
||||||
|
})
|
||||||
|
|
||||||
|
if (comparison.snapshot_warnings.trim() !== '') {
|
||||||
|
core.info(comparison.snapshot_warnings)
|
||||||
|
if (retryOpts !== undefined) {
|
||||||
|
if (retryOpts.retryUntil < Date.now()) {
|
||||||
|
core.info(`Retry timeout exceeded. Proceeding...`)
|
||||||
|
return comparison
|
||||||
|
} else {
|
||||||
|
core.info(`Retrying in ${retryOpts.retryDelay} seconds...`)
|
||||||
|
await delay(retryOpts.retryDelay * 1000)
|
||||||
|
return getComparison(baseRef, headRef, retryOpts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return comparison
|
||||||
|
}
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
async function run(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const config = await readConfig()
|
const config = await readConfig()
|
||||||
|
|
||||||
const refs = getRefs(config, github.context)
|
const refs = getRefs(config, github.context)
|
||||||
|
|
||||||
const comparison = await dependencyGraph.compare({
|
const comparison = await getComparison(
|
||||||
owner: github.context.repo.owner,
|
refs.base,
|
||||||
repo: github.context.repo.repo,
|
refs.head,
|
||||||
baseRef: refs.base,
|
config.retry_on_snapshot_warnings
|
||||||
headRef: refs.head
|
? {
|
||||||
})
|
retryUntil:
|
||||||
|
Date.now() + config.retry_on_snapshot_warnings_timeout * 1000,
|
||||||
|
retryDelay: 10
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
)
|
||||||
|
|
||||||
const changes = comparison.changes
|
const changes = comparison.changes
|
||||||
const snapshot_warnings = comparison.snapshot_warnings
|
const snapshot_warnings = comparison.snapshot_warnings
|
||||||
|
|
||||||
@@ -38,21 +80,17 @@ async function run(): Promise<void> {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const minSeverity = config.fail_on_severity
|
|
||||||
const scopedChanges = filterChangesByScopes(config.fail_on_scopes, changes)
|
const scopedChanges = filterChangesByScopes(config.fail_on_scopes, changes)
|
||||||
|
|
||||||
const filteredChanges = filterAllowedAdvisories(
|
const filteredChanges = filterAllowedAdvisories(
|
||||||
config.allow_ghsas,
|
config.allow_ghsas,
|
||||||
scopedChanges
|
scopedChanges
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const minSeverity = config.fail_on_severity
|
||||||
const vulnerableChanges = filterChangesBySeverity(
|
const vulnerableChanges = filterChangesBySeverity(
|
||||||
minSeverity,
|
minSeverity,
|
||||||
filteredChanges
|
filteredChanges
|
||||||
).filter(
|
|
||||||
change =>
|
|
||||||
change.change_type === 'added' &&
|
|
||||||
change.vulnerabilities !== undefined &&
|
|
||||||
change.vulnerabilities.length > 0
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const invalidLicenseChanges = await getInvalidLicenseChanges(
|
const invalidLicenseChanges = await getInvalidLicenseChanges(
|
||||||
@@ -81,7 +119,7 @@ async function run(): Promise<void> {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (snapshot_warnings) {
|
if (snapshot_warnings) {
|
||||||
summary.addSnapshotWarnings(snapshot_warnings)
|
summary.addSnapshotWarnings(config, snapshot_warnings)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.vulnerability_check) {
|
if (config.vulnerability_check) {
|
||||||
@@ -99,7 +137,11 @@ async function run(): Promise<void> {
|
|||||||
|
|
||||||
summary.addScannedDependencies(changes)
|
summary.addScannedDependencies(changes)
|
||||||
printScannedDependencies(changes)
|
printScannedDependencies(changes)
|
||||||
if (config.comment_summary_in_pr) {
|
if (
|
||||||
|
config.comment_summary_in_pr === 'always' ||
|
||||||
|
(config.comment_summary_in_pr === 'on-failure' &&
|
||||||
|
process.exitCode === core.ExitCode.Failure)
|
||||||
|
) {
|
||||||
await commentPr(core.summary)
|
await commentPr(core.summary)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
+19
-1
@@ -49,7 +49,25 @@ export const ConfigurationOptionsSchema = z
|
|||||||
config_file: z.string().optional(),
|
config_file: z.string().optional(),
|
||||||
base_ref: z.string().optional(),
|
base_ref: z.string().optional(),
|
||||||
head_ref: z.string().optional(),
|
head_ref: z.string().optional(),
|
||||||
comment_summary_in_pr: z.boolean().default(false)
|
retry_on_snapshot_warnings: z.boolean().default(false),
|
||||||
|
retry_on_snapshot_warnings_timeout: z.number().default(120),
|
||||||
|
comment_summary_in_pr: z
|
||||||
|
.union([
|
||||||
|
z.preprocess(
|
||||||
|
val => (val === 'true' ? true : val === 'false' ? false : val),
|
||||||
|
z.boolean()
|
||||||
|
),
|
||||||
|
z.enum(['always', 'never', 'on-failure'])
|
||||||
|
])
|
||||||
|
.default('never')
|
||||||
|
})
|
||||||
|
.transform(config => {
|
||||||
|
if (config.comment_summary_in_pr === true) {
|
||||||
|
config.comment_summary_in_pr = 'always'
|
||||||
|
} else if (config.comment_summary_in_pr === false) {
|
||||||
|
config.comment_summary_in_pr = 'never'
|
||||||
|
}
|
||||||
|
return config
|
||||||
})
|
})
|
||||||
.superRefine((config, context) => {
|
.superRefine((config, context) => {
|
||||||
if (config.allow_licenses && config.deny_licenses) {
|
if (config.allow_licenses && config.deny_licenses) {
|
||||||
|
|||||||
+24
-11
@@ -231,21 +231,34 @@ export function addScannedDependencies(changes: Changes): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addSnapshotWarnings(warnings: string): void {
|
function snapshotWarningRecommendation(
|
||||||
// For now, we want to ignore warnings that just complain
|
config: ConfigurationOptions,
|
||||||
// about missing snapshots on the head SHA. This is a product
|
warnings: string
|
||||||
// decision to avoid presenting warnings to users who simply
|
): string {
|
||||||
// don't use snapshots.
|
const no_pr_snaps = warnings.includes(
|
||||||
const ignore_regex = new RegExp(/No.*snapshot.*found.*head.*/, 'i')
|
'No snapshots were found for the head SHA'
|
||||||
if (ignore_regex.test(warnings)) {
|
)
|
||||||
return
|
const retries_disabled = !config.retry_on_snapshot_warnings
|
||||||
|
if (no_pr_snaps && retries_disabled) {
|
||||||
|
return 'Ensure that dependencies are being submitted on PR branches and consider enabling <em>retry-on-snapshot-warnings</em>.'
|
||||||
|
} else if (no_pr_snaps) {
|
||||||
|
return 'Ensure that dependencies are being submitted on PR branches. Re-running this action after a short time may resolve the issue.'
|
||||||
|
} else if (retries_disabled) {
|
||||||
|
return 'Consider enabling <em>retry-on-snapshot-warnings</em>.'
|
||||||
}
|
}
|
||||||
|
return 'Re-running this action after a short time may resolve the issue.'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addSnapshotWarnings(
|
||||||
|
config: ConfigurationOptions,
|
||||||
|
warnings: string
|
||||||
|
): void {
|
||||||
core.summary.addHeading('Snapshot Warnings', 2)
|
core.summary.addHeading('Snapshot Warnings', 2)
|
||||||
core.summary.addQuote(`${icons.warning}: ${warnings}`)
|
core.summary.addQuote(`${icons.warning}: ${warnings}`)
|
||||||
core.summary.addRaw(
|
const recommendation = snapshotWarningRecommendation(config, warnings)
|
||||||
'Re-running this action after a short time may resolve the issue. See the documentation for more information and troubleshooting advice.'
|
const docsLink =
|
||||||
)
|
'See <a href="https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#best-practices-for-using-the-dependency-review-api-and-the-dependency-submission-api-together">the documentation</a> for more information and troubleshooting advice.'
|
||||||
|
core.summary.addRaw(`${recommendation} ${docsLink}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
function countLicenseIssues(
|
function countLicenseIssues(
|
||||||
|
|||||||
Reference in New Issue
Block a user