Compare commits
173 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c77673abe0 | |||
| efd78809f9 | |||
| e91b527bcb | |||
| f508195cbc | |||
| ef8bfcec89 | |||
| 31cb4e05f7 | |||
| 7920884bc8 | |||
| aae0422a7f | |||
| 46d2ba8805 | |||
| 7c07c1da42 | |||
| 6e3a1cfe9e | |||
| 3190101729 | |||
| 3576f26c76 | |||
| 97fef8f979 | |||
| 60e20b95c9 | |||
| e6aba92fb0 | |||
| 4b2cf01947 | |||
| 33b11b63b3 | |||
| 90014ebf46 | |||
| c0fcb40fb5 | |||
| 6213daabf8 | |||
| 6c62d64ea3 | |||
| 6154af02da | |||
| df40ce1edc | |||
| a033837e12 | |||
| d79457303f | |||
| b2f83f35c7 | |||
| 389b38eb1a | |||
| e3926a59f5 | |||
| 54656aadd8 | |||
| f02b9fb886 | |||
| 6587f9feee | |||
| cab2d5f36f | |||
| ef411f3a4c | |||
| 589f46e5a2 | |||
| a482eabd84 | |||
| c63a70f2bb | |||
| ea081cab93 | |||
| 78231376d4 | |||
| ea38797bf9 | |||
| 383b34b013 | |||
| 234f1c3e6b | |||
| 1aca439347 | |||
| f5231a7139 | |||
| 872c5e3689 | |||
| 86e4c38e88 | |||
| 70a13ae7e3 | |||
| 0ff3da6f81 | |||
| 6d88398316 | |||
| 29022577bf | |||
| a4bf690c47 | |||
| 3f67248108 | |||
| e82e9497cb | |||
| 945cb4d00a | |||
| 459b39211c | |||
| c109d3f46d | |||
| 706aa54d76 | |||
| 12cfe866a8 | |||
| 0caa632377 | |||
| df02ee7d42 | |||
| 38e9237630 | |||
| 03c7962be5 | |||
| cff3674e25 | |||
| a184554be2 | |||
| 660812709b | |||
| d8b4cd80d5 | |||
| 8e5d487bb8 | |||
| 3e6e055a26 | |||
| 1f8d096c90 | |||
| 0247f51a25 | |||
| f599dc7887 | |||
| 6919a4885f | |||
| 8f97494d2e | |||
| 08ec176670 | |||
| 40a9da4614 | |||
| 9ad1f84ed2 | |||
| 464e6ac735 | |||
| 141e2dae22 | |||
| 37bb7a46dd | |||
| 5abb42a215 | |||
| 5aafbe4a32 | |||
| d623612924 | |||
| 08fe899167 | |||
| 067e030d27 | |||
| 6b47d2662b | |||
| 290634fe98 | |||
| 352f50a80e | |||
| 11310527b4 | |||
| ea0f46928b | |||
| 369356e2e7 | |||
| 13fe21bc0a | |||
| 136c0838bf | |||
| 8ed85b3757 | |||
| a952d7b1b7 | |||
| b8e622f102 | |||
| ac059c649c | |||
| 93652d7af0 | |||
| ba127cac5e | |||
| 1dd7392739 | |||
| 8f801ec4bb | |||
| 2d265aa7cc | |||
| c57c602135 | |||
| c2097b2a9b | |||
| 0a055a6a13 | |||
| 3417e62ba2 | |||
| 49fecaf158 | |||
| 173a4b8d96 | |||
| db1829cd87 | |||
| d87317e782 | |||
| 30d5821115 | |||
| 6e42c3395a | |||
| a3074cd699 | |||
| 51a29d6960 | |||
| 235a221cf4 | |||
| 9b3a7f61dd | |||
| a4761312ac | |||
| 28c7c8c314 | |||
| 9da0fd4871 | |||
| fe45fd6645 | |||
| c41b9f9cfb | |||
| 10c5aa9564 | |||
| 8e5000107a | |||
| 89a074ec7e | |||
| 8d7a4c48ad | |||
| 2f59625b62 | |||
| 9e552623cc | |||
| 4108a15bd3 | |||
| 5ea8fbfb83 | |||
| c72eb06e71 | |||
| aa409fa6cd | |||
| 5aaa78ce3c | |||
| 8d9ea3eb63 | |||
| 59a4f4c4ba | |||
| bf8cfe8b38 | |||
| ae538ebe32 | |||
| b4126ce983 | |||
| 418ae59d51 | |||
| c38007a979 | |||
| ebe5527e72 | |||
| 1589654682 | |||
| f0ff0b670a | |||
| 336da03de2 | |||
| 78565a954f | |||
| 3c73a622ba | |||
| 7a42af0f2f | |||
| abfd4a1fc7 | |||
| 40e460b464 | |||
| 9f1bc9b354 | |||
| 774bd6c1d5 | |||
| f7686f8c21 | |||
| 688e92b5e5 | |||
| 7ce779229f | |||
| 543eecb644 | |||
| a7ec2eb771 | |||
| 13455c7175 | |||
| 6d941b396a | |||
| 49ed3f2876 | |||
| b55cddb69d | |||
| dcdeb7de77 | |||
| b4a2fbfa16 | |||
| 97e5a607ba | |||
| 3b410dc4ad | |||
| 683cbc4872 | |||
| 2f696d8c7a | |||
| 1a9033d563 | |||
| ad6e320da1 | |||
| 3d86825394 | |||
| 10dc05ba09 | |||
| 04f48dec81 | |||
| bb5c0c7ca0 | |||
| 2d7d700469 | |||
| 9760f87258 | |||
| 74c047086c |
@@ -3,12 +3,12 @@ updates:
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
interval: weekly
|
||||
|
||||
- package-ecosystem: npm
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
interval: weekly
|
||||
ignore:
|
||||
- dependency-name: '@types/node'
|
||||
update-types: ['version-update:semver-major']
|
||||
|
||||
@@ -27,6 +27,7 @@ jobs:
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.x
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
+2
-2
@@ -112,8 +112,8 @@ minor/patch updates.
|
||||
To do this just checkout `main`, force-create a new annotated tag, and push it:
|
||||
|
||||
```
|
||||
git tag -fa v2 -m "Updating v2 to 2.3.4"
|
||||
git push origin v2 --force
|
||||
git tag -fa v3 -m "Updating v3 to 3.0.1"
|
||||
git push origin v3 --force
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
@@ -5,11 +5,11 @@ raise an error if any vulnerabilities or invalid licenses are being introduced.
|
||||
|
||||
The action is available for all public repositories, as well as private repositories that have GitHub Advanced Security licensed.
|
||||
|
||||
You can see the results on the job logs
|
||||
You can see the results on the job logs:
|
||||
|
||||
<img width="854" alt="Screen Shot 2022-03-31 at 1 10 51 PM" src="https://user-images.githubusercontent.com/2161/161042286-b22d7dd3-13cb-458d-8744-ce70ed9bf562.png">
|
||||
|
||||
or on the job summary
|
||||
or on the job summary:
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/7847935/182871416-50332bbb-b279-4621-a136-ca72a4314301.png">
|
||||
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@v3
|
||||
- name: 'Dependency Review'
|
||||
uses: actions/dependency-review-action@v2
|
||||
uses: actions/dependency-review-action@v3
|
||||
```
|
||||
|
||||
### GitHub Enterprise Server
|
||||
@@ -59,163 +59,34 @@ jobs:
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@v3
|
||||
- name: 'Dependency Review'
|
||||
uses: actions/dependency-review-action@v2
|
||||
uses: actions/dependency-review-action@v3
|
||||
```
|
||||
|
||||
## Configuration
|
||||
## Configuration options
|
||||
|
||||
Configure this action by either using an external configuration file,
|
||||
or by inlining these options in your workflow file.
|
||||
Configure this action by either inlining these options in your workflow file, or by using an external configuration file. All configuration options are optional.
|
||||
|
||||
## Configuration Options
|
||||
| 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` |
|
||||
| `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 |
|
||||
| `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 |
|
||||
| `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` |
|
||||
| `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 |
|
||||
|
||||
### config-file
|
||||
*not supported for use with GitHub Enterprise Server
|
||||
|
||||
A string representing the path to an external configuration file. By
|
||||
default external configuration files are not used.
|
||||
†will be supported with GitHub Enterprise Server 3.8
|
||||
|
||||
**Possible values**: A string representing the absolute path to the
|
||||
configuration file.
|
||||
|
||||
**Example**: `config-file: ./.github/dependency-review-config.yml`.
|
||||
|
||||
### fail-on-severity
|
||||
|
||||
Configure the severity level for alerting. See "[Vulnerability Severity](https://github.com/actions/dependency-review-action#vulnerability-severity)".
|
||||
|
||||
**Possible values**: `critical`, `high`, `moderate`, `low`.
|
||||
|
||||
**Example**: `fail-on-severity: moderate`.
|
||||
|
||||
### fail-on-scopes
|
||||
|
||||
A list of strings representing the build environments you want to
|
||||
support. The default value is `development, runtime`.
|
||||
|
||||
**Possible values**: `development`, `runtime`, `unknown`
|
||||
|
||||
**Inline example**: `fail-on-scopes: development, runtime`
|
||||
|
||||
**YAML example**:
|
||||
|
||||
```yaml
|
||||
# this prevents scanning development dependencies
|
||||
fail-on-scopes:
|
||||
- runtime
|
||||
```
|
||||
|
||||
### allow-licenses
|
||||
|
||||
Only allow the licenses that comply with the expressions in this list. See "[Licenses](https://github.com/actions/dependency-review-action#licenses)".
|
||||
|
||||
**Possible values**: A list of of [SPDX-compliant license identifiers](https://spdx.org/licenses/).
|
||||
|
||||
**Inline example**: `allow-licenses: BSD-3-Clause, LGPL-2.1 OR MIT OR BSD-3-Clause`
|
||||
|
||||
**YAML example**:
|
||||
|
||||
```yaml
|
||||
allow-licenses:
|
||||
- BSD-3-Clause
|
||||
- LGPL-2.1
|
||||
- MIT
|
||||
- BSD-3-Clause
|
||||
```
|
||||
|
||||
### deny-licenses
|
||||
|
||||
Add a custom list of licenses you want to block. See
|
||||
"[Licenses](https://github.com/actions/dependency-review-action#licenses)".
|
||||
|
||||
**Possible values**: Any valid set of [SPDX licenses](https://spdx.org/licenses/).
|
||||
|
||||
**Inline example**: `deny-licenses: LGPL-2.0, GPL-2.0+ WITH Bison-exception-2.2`
|
||||
|
||||
**YAML example**:
|
||||
|
||||
```yaml
|
||||
deny-licenses:
|
||||
- LGPL-2.0
|
||||
- GPL-2.0+ WITH Bison-exception-2.2
|
||||
```
|
||||
|
||||
### allow-ghsas
|
||||
|
||||
Add a custom list of GitHub Advisory IDs that can be skipped during detection.
|
||||
|
||||
**Possible values**: Any valid advisory GHSA ids.
|
||||
|
||||
**Inline example**: `allow-ghsas: GHSA-abcd-1234-5679, GHSA-efgh-1234-5679`
|
||||
|
||||
**YAML example**:
|
||||
|
||||
```yaml
|
||||
allow-ghsas:
|
||||
- GHSA-abcd-1234-5679
|
||||
- GHSA-efgh-1234-5679
|
||||
```
|
||||
|
||||
### license-check/vulnerability-check
|
||||
|
||||
Disable the license checks or vulnerability checks performed by this Action.
|
||||
You can't disable both checks.
|
||||
|
||||
**Possible values**: `true` or `false`
|
||||
|
||||
**Example**:
|
||||
|
||||
```yaml
|
||||
license-check: true
|
||||
vulnerability-check: false
|
||||
```
|
||||
|
||||
### base-ref/head-ref
|
||||
|
||||
Provide custom git references for the git base/head when performing
|
||||
the comparison. If you are using pull requests, or
|
||||
`pull_request_target` events you do not need to worry about setting
|
||||
this. The values need to be specified for all other event types.
|
||||
|
||||
**Possible values**: Any valid git ref(s) in your project.
|
||||
|
||||
**Example**:
|
||||
|
||||
```yaml
|
||||
base-ref: 8bb8a58d6a4028b6c2e314d5caaf273f57644896
|
||||
head-ref: 69af5638bf660cf218aad5709a4c100e42a2f37b
|
||||
```
|
||||
|
||||
### Configuration File
|
||||
|
||||
You can use an external configuration file to specify the settings for
|
||||
this Action.
|
||||
|
||||
Start by specifying that you will be using an external configuration
|
||||
file:
|
||||
|
||||
```yaml
|
||||
- name: Dependency Review
|
||||
uses: actions/dependency-review-action@v2
|
||||
with:
|
||||
config-file: './.github/dependency-review-config.yml'
|
||||
```
|
||||
|
||||
And then create the file in the path you just specified. **All of these fields are
|
||||
optional**:
|
||||
|
||||
```yaml
|
||||
fail-on-severity: 'critical'
|
||||
allow-licenses:
|
||||
- 'GPL-3.0'
|
||||
- 'BSD-3-Clause'
|
||||
- 'MIT'
|
||||
```
|
||||
|
||||
### Inline Configuration
|
||||
|
||||
You can pass options to the Dependency Review
|
||||
Action using your workflow file. Here's an example of what the full
|
||||
file would look like:
|
||||
You can pass options to the Dependency Review GitHub Action using your workflow file.
|
||||
|
||||
#### Example
|
||||
|
||||
```yaml
|
||||
name: 'Dependency Review'
|
||||
@@ -229,7 +100,7 @@ jobs:
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@v3
|
||||
- name: Dependency Review
|
||||
uses: actions/dependency-review-action@v2
|
||||
uses: actions/dependency-review-action@v3
|
||||
with:
|
||||
fail-on-severity: moderate
|
||||
|
||||
@@ -237,71 +108,41 @@ jobs:
|
||||
deny-licenses: LGPL-2.0, BSD-2-Clause
|
||||
```
|
||||
|
||||
### Vulnerability Severity
|
||||
### Configuration File
|
||||
|
||||
By default the action will fail on any pull request that contains a
|
||||
vulnerable dependency, regardless of the severity level. You can override this behavior by
|
||||
using the `fail-on-severity` option, which will cause a failure on any pull requests that introduce vulnerabilities of the specified severity level or higher. The possible values are: `critical`, `high`, `moderate`, or `low`. The
|
||||
action defaults to `low`.
|
||||
You can use an external configuration file to specify the settings for this action. It can be a local file or a file in an external repository. Refer to the following options for the specification.
|
||||
|
||||
This example will only fail on pull requests with `critical` and `high` vulnerabilities:
|
||||
| Option | Usage | Possible values |
|
||||
|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `config-file` | A path to a file in the current repository or an external repository. Use this syntax for external files: `OWNER/REPOSITORY/FILENAME@BRANCH` | **Local file**: `./.github/dependency-review-config.yml` <br> **External repo**: `github/octorepo/dependency-review-config.yml@main` |
|
||||
| `external-repo-token` | Specifies a token for fetching the configuration file. It is required if the file resides in a private external repository and for all GitHub Enterprise Server repositories. Create a token in [developer settings](https://github.com/settings/tokens). | Any token with `read` permissions to the repository hosting the config file. |
|
||||
|
||||
#### Example
|
||||
|
||||
Start by specifying that you will be using an external configuration file:
|
||||
|
||||
```yaml
|
||||
- name: Dependency Review
|
||||
uses: actions/dependency-review-action@v2
|
||||
with:
|
||||
fail-on-severity: high
|
||||
config-file: './.github/dependency-review-config.yml'
|
||||
```
|
||||
|
||||
### Dependency Scoping
|
||||
|
||||
By default the action will only fail on `runtime` dependencies that have vulnerabilities or unacceptable licenses, ignoring `development` dependencies. You can override this behavior with the `fail-on-scopes` option, which will allow you to list the specific dependency scopes you care about. The possible values are: `unknown`, `runtime`, and `development`. Note: Filtering by scope will not be supported on Enterprise Server just yet, as the REST API's introduction of `scope` will be released in an upcoming Enterprise Server version. We will treat all dependencies on Enterprise Server as having a `runtime` scope and thus will not be filtered away.
|
||||
And then create the file in the path you just specified:
|
||||
|
||||
```yaml
|
||||
- name: Dependency Review
|
||||
uses: actions/dependency-review-action@v2
|
||||
with:
|
||||
fail-on-scopes: runtime, development
|
||||
```
|
||||
|
||||
### Licenses
|
||||
|
||||
You can set the action to fail on pull requests based on the licenses of the dependencies
|
||||
they introduce. With `allow-licenses` you can define the list of licenses
|
||||
your repository will accept. Alternatively, you can use `deny-licenses` to only
|
||||
forbid a subset of licenses. These options are not supported on Enterprise Server.
|
||||
|
||||
You can use the [Licenses
|
||||
API](https://docs.github.com/en/rest/licenses) to see the full list of
|
||||
supported licenses. Use [SPDX licenses](https://spdx.org/licenses/)
|
||||
to filter the licenses. A couple of examples:
|
||||
|
||||
```yaml
|
||||
# only allow MIT-licensed dependents
|
||||
- name: Dependency Review
|
||||
uses: actions/dependency-review-action@v2
|
||||
with:
|
||||
allow-licenses: MIT
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Block Apache 1.1 and 2.0 licensed dependents
|
||||
- name: Dependency Review
|
||||
uses: actions/dependency-review-action@v2
|
||||
with:
|
||||
deny-licenses: Apache-1.1+
|
||||
fail-on-severity: 'critical'
|
||||
allow-licenses:
|
||||
- 'GPL-3.0'
|
||||
- 'BSD-3-Clause'
|
||||
- 'MIT'
|
||||
```
|
||||
|
||||
### Considerations
|
||||
|
||||
- Checking for licenses is not supported on Enterprise Server.
|
||||
- The action will only accept one of the two parameters; an error will
|
||||
be raised if you provide both.
|
||||
- By default both parameters are empty (no license checking is
|
||||
performed).
|
||||
- We don't have license information for all of your dependents. If we
|
||||
can't detect the license for a dependency **we will inform you, but the
|
||||
action won't fail**.
|
||||
- The action will only accept one of the two `license` parameters; an error will be raised if you provide both.
|
||||
- We don't have license information for all of your dependents. If we can't detect the license for a dependency **we will inform you, but the action won't fail**.
|
||||
|
||||
## Blocking pull requests
|
||||
|
||||
@@ -309,14 +150,11 @@ The Dependency Review GitHub Action check will only block a pull request from be
|
||||
|
||||
## Getting help
|
||||
|
||||
If you have bug reports, questions or suggestions please [create a new
|
||||
issue](https://github.com/actions/dependency-review-action/issues/new/choose).
|
||||
If you have bug reports, questions or suggestions please [create a new issue](https://github.com/actions/dependency-review-action/issues/new/choose).
|
||||
|
||||
## Contributing
|
||||
|
||||
We are grateful for any contributions made to this project.
|
||||
|
||||
Please read [CONTRIBUTING.MD](https://github.com/actions/dependency-review-action/blob/main/CONTRIBUTING.md) to get started.
|
||||
We are grateful for any contributions made to this project. Please read [CONTRIBUTING.MD](https://github.com/actions/dependency-review-action/blob/main/CONTRIBUTING.md) to get started.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
+91
-72
@@ -1,5 +1,5 @@
|
||||
import {expect, test, beforeEach} from '@jest/globals'
|
||||
import {readConfig, readConfigFile} from '../src/config'
|
||||
import {readConfig} from '../src/config'
|
||||
import {getRefs} from '../src/git-refs'
|
||||
import * as Utils from '../src/utils'
|
||||
|
||||
@@ -39,43 +39,53 @@ beforeEach(() => {
|
||||
})
|
||||
|
||||
test('it defaults to low severity', async () => {
|
||||
const options = readConfig()
|
||||
expect(options.fail_on_severity).toEqual('low')
|
||||
const config = await readConfig()
|
||||
expect(config.fail_on_severity).toEqual('low')
|
||||
})
|
||||
|
||||
test('it reads custom configs', async () => {
|
||||
setInput('fail-on-severity', 'critical')
|
||||
setInput('allow-licenses', ' BSD, GPL 2')
|
||||
|
||||
const options = readConfig()
|
||||
expect(options.fail_on_severity).toEqual('critical')
|
||||
expect(options.allow_licenses).toEqual(['BSD', 'GPL 2'])
|
||||
const config = await readConfig()
|
||||
expect(config.fail_on_severity).toEqual('critical')
|
||||
expect(config.allow_licenses).toEqual(['BSD', 'GPL 2'])
|
||||
})
|
||||
|
||||
test('it defaults to empty allow/deny lists ', async () => {
|
||||
const options = readConfig()
|
||||
const config = await readConfig()
|
||||
|
||||
expect(options.allow_licenses).toEqual(undefined)
|
||||
expect(options.deny_licenses).toEqual(undefined)
|
||||
expect(config.allow_licenses).toEqual(undefined)
|
||||
expect(config.deny_licenses).toEqual(undefined)
|
||||
})
|
||||
|
||||
test('it raises an error if both an allow and denylist are specified', async () => {
|
||||
setInput('allow-licenses', 'MIT')
|
||||
setInput('deny-licenses', 'BSD')
|
||||
|
||||
expect(() => readConfig()).toThrow()
|
||||
await expect(readConfig()).rejects.toThrow(
|
||||
'You cannot specify both allow-licenses and deny-licenses'
|
||||
)
|
||||
})
|
||||
test('it raises an error if an empty allow list is specified', async () => {
|
||||
setInput('config-file', './__tests__/fixtures/config-empty-allow-sample.yml')
|
||||
|
||||
await expect(readConfig()).rejects.toThrow(
|
||||
'You should provide at least one license in allow-licenses'
|
||||
)
|
||||
})
|
||||
|
||||
test('it raises an error when given an unknown severity', async () => {
|
||||
setInput('fail-on-severity', 'zombies')
|
||||
expect(() => readConfig()).toThrow()
|
||||
|
||||
await expect(readConfig()).rejects.toThrow(/received 'zombies'/)
|
||||
})
|
||||
|
||||
test('it uses the given refs when the event is not a pull request', async () => {
|
||||
setInput('base-ref', 'a-custom-base-ref')
|
||||
setInput('head-ref', 'a-custom-head-ref')
|
||||
|
||||
const refs = getRefs(readConfig(), {
|
||||
const refs = getRefs(await readConfig(), {
|
||||
payload: {},
|
||||
eventName: 'workflow_dispatch'
|
||||
})
|
||||
@@ -84,9 +94,9 @@ test('it uses the given refs when the event is not a pull request', async () =>
|
||||
})
|
||||
|
||||
test('it raises an error when no refs are provided and the event is not a pull request', async () => {
|
||||
const options = readConfig()
|
||||
const config = await readConfig()
|
||||
expect(() =>
|
||||
getRefs(options, {
|
||||
getRefs(config, {
|
||||
payload: {},
|
||||
eventName: 'workflow_dispatch'
|
||||
})
|
||||
@@ -94,133 +104,142 @@ test('it raises an error when no refs are provided and the event is not a pull r
|
||||
})
|
||||
|
||||
test('it reads an external config file', async () => {
|
||||
let options = readConfigFile('./__tests__/fixtures/config-allow-sample.yml')
|
||||
expect(options.fail_on_severity).toEqual('critical')
|
||||
expect(options.allow_licenses).toEqual(['BSD', 'GPL 2'])
|
||||
setInput('config-file', './__tests__/fixtures/config-allow-sample.yml')
|
||||
|
||||
const config = await readConfig()
|
||||
expect(config.fail_on_severity).toEqual('critical')
|
||||
expect(config.allow_licenses).toEqual(['BSD', 'GPL 2'])
|
||||
})
|
||||
|
||||
test('raises an error when the the config file was not found', async () => {
|
||||
expect(() => readConfigFile('fixtures/i-dont-exist')).toThrow()
|
||||
test('raises an error when the config file was not found', async () => {
|
||||
setInput('config-file', 'fixtures/i-dont-exist')
|
||||
await expect(readConfig()).rejects.toThrow(/Unable to fetch/)
|
||||
})
|
||||
|
||||
test('it parses options from both sources', async () => {
|
||||
setInput('config-file', './__tests__/fixtures/config-allow-sample.yml')
|
||||
|
||||
let options = readConfig()
|
||||
expect(options.fail_on_severity).toEqual('critical')
|
||||
let config = await readConfig()
|
||||
expect(config.fail_on_severity).toEqual('critical')
|
||||
|
||||
setInput('base-ref', 'a-custom-base-ref')
|
||||
options = readConfig()
|
||||
expect(options.base_ref).toEqual('a-custom-base-ref')
|
||||
config = await readConfig()
|
||||
expect(config.base_ref).toEqual('a-custom-base-ref')
|
||||
})
|
||||
|
||||
test('in case of conflicts, the external config is the source of truth', async () => {
|
||||
test('in case of conflicts, the inline config is the source of truth', async () => {
|
||||
setInput('fail-on-severity', 'low')
|
||||
setInput('config-file', './__tests__/fixtures/config-allow-sample.yml') // this will set fail-on-severity to 'critical'
|
||||
|
||||
let options = readConfig()
|
||||
expect(options.fail_on_severity).toEqual('critical')
|
||||
|
||||
// this should not overwite the previous value
|
||||
setInput('fail-on-severity', 'low')
|
||||
options = readConfig()
|
||||
expect(options.fail_on_severity).toEqual('critical')
|
||||
const config = await readConfig()
|
||||
expect(config.fail_on_severity).toEqual('low')
|
||||
})
|
||||
|
||||
test('it uses the default values when loading external files', async () => {
|
||||
setInput('config-file', './__tests__/fixtures/no-licenses-config.yml')
|
||||
let options = readConfig()
|
||||
expect(options.allow_licenses).toEqual(undefined)
|
||||
expect(options.deny_licenses).toEqual(undefined)
|
||||
let config = await readConfig()
|
||||
expect(config.allow_licenses).toEqual(undefined)
|
||||
expect(config.deny_licenses).toEqual(undefined)
|
||||
|
||||
setInput('config-file', './__tests__/fixtures/license-config-sample.yml')
|
||||
options = readConfig()
|
||||
expect(options.fail_on_severity).toEqual('low')
|
||||
config = await readConfig()
|
||||
expect(config.fail_on_severity).toEqual('low')
|
||||
})
|
||||
|
||||
test('it accepts an external configuration filename', async () => {
|
||||
setInput('config-file', './__tests__/fixtures/no-licenses-config.yml')
|
||||
const options = readConfig()
|
||||
expect(options.fail_on_severity).toEqual('critical')
|
||||
const config = await readConfig()
|
||||
expect(config.fail_on_severity).toEqual('critical')
|
||||
})
|
||||
|
||||
test('it raises an error when given an unknown severity in an external config file', async () => {
|
||||
setInput('config-file', './__tests__/fixtures/invalid-severity-config.yml')
|
||||
expect(() => readConfig()).toThrow()
|
||||
await expect(readConfig()).rejects.toThrow()
|
||||
})
|
||||
|
||||
test('it defaults to runtime scope', async () => {
|
||||
const options = readConfig()
|
||||
expect(options.fail_on_scopes).toEqual(['runtime'])
|
||||
const config = await readConfig()
|
||||
expect(config.fail_on_scopes).toEqual(['runtime'])
|
||||
})
|
||||
|
||||
test('it parses custom scopes preference', async () => {
|
||||
setInput('fail-on-scopes', 'runtime, development')
|
||||
let options = readConfig()
|
||||
expect(options.fail_on_scopes).toEqual(['runtime', 'development'])
|
||||
let config = await readConfig()
|
||||
expect(config.fail_on_scopes).toEqual(['runtime', 'development'])
|
||||
|
||||
clearInputs()
|
||||
setInput('fail-on-scopes', 'development')
|
||||
options = readConfig()
|
||||
expect(options.fail_on_scopes).toEqual(['development'])
|
||||
config = await readConfig()
|
||||
expect(config.fail_on_scopes).toEqual(['development'])
|
||||
})
|
||||
|
||||
test('it raises an error when given invalid scope', async () => {
|
||||
setInput('fail-on-scopes', 'runtime, zombies')
|
||||
expect(() => readConfig()).toThrow()
|
||||
await expect(readConfig()).rejects.toThrow(/received 'zombies'/)
|
||||
})
|
||||
|
||||
test('it defaults to an empty GHSA allowlist', async () => {
|
||||
const options = readConfig()
|
||||
expect(options.allow_ghsas).toEqual(undefined)
|
||||
const config = await readConfig()
|
||||
expect(config.allow_ghsas).toEqual([])
|
||||
})
|
||||
|
||||
test('it successfully parses GHSA allowlist', async () => {
|
||||
setInput('allow-ghsas', 'GHSA-abcd-1234-5679, GHSA-efgh-1234-5679')
|
||||
const options = readConfig()
|
||||
expect(options.allow_ghsas).toEqual([
|
||||
const config = await readConfig()
|
||||
expect(config.allow_ghsas).toEqual([
|
||||
'GHSA-abcd-1234-5679',
|
||||
'GHSA-efgh-1234-5679'
|
||||
])
|
||||
})
|
||||
|
||||
test('it defaults to checking licenses', async () => {
|
||||
const options = readConfig()
|
||||
expect(options.license_check).toBe(true)
|
||||
const config = await readConfig()
|
||||
expect(config.license_check).toBe(true)
|
||||
})
|
||||
|
||||
test('it parses the license-check input', async () => {
|
||||
setInput('license-check', 'false')
|
||||
let options = readConfig()
|
||||
expect(options.license_check).toEqual(false)
|
||||
let config = await readConfig()
|
||||
expect(config.license_check).toEqual(false)
|
||||
|
||||
clearInputs()
|
||||
setInput('license-check', 'true')
|
||||
options = readConfig()
|
||||
expect(options.license_check).toEqual(true)
|
||||
config = await readConfig()
|
||||
expect(config.license_check).toEqual(true)
|
||||
})
|
||||
|
||||
test('it defaults to checking vulnerabilities', async () => {
|
||||
const options = readConfig()
|
||||
expect(options.vulnerability_check).toBe(true)
|
||||
const config = await readConfig()
|
||||
expect(config.vulnerability_check).toBe(true)
|
||||
})
|
||||
|
||||
test('it parses the vulnerability-check input', async () => {
|
||||
setInput('vulnerability-check', 'false')
|
||||
let options = readConfig()
|
||||
expect(options.vulnerability_check).toEqual(false)
|
||||
let config = await readConfig()
|
||||
expect(config.vulnerability_check).toEqual(false)
|
||||
|
||||
clearInputs()
|
||||
setInput('vulnerability-check', 'true')
|
||||
options = readConfig()
|
||||
expect(options.vulnerability_check).toEqual(true)
|
||||
config = await readConfig()
|
||||
expect(config.vulnerability_check).toEqual(true)
|
||||
})
|
||||
|
||||
test('it is not impossible to disable both checks', async () => {
|
||||
test('it is not possible to disable both checks', async () => {
|
||||
setInput('license-check', 'false')
|
||||
setInput('vulnerability-check', 'false')
|
||||
expect(() => {
|
||||
readConfig()
|
||||
}).toThrow("Can't disable both license-check and vulnerability-check")
|
||||
await expect(readConfig()).rejects.toThrow(
|
||||
/Can't disable both license-check and vulnerability-check/
|
||||
)
|
||||
})
|
||||
|
||||
test('it supports comma-separated lists', async () => {
|
||||
setInput(
|
||||
'config-file',
|
||||
'./__tests__/fixtures/inline-license-config-sample.yml'
|
||||
)
|
||||
let config = await readConfig()
|
||||
|
||||
expect(config.allow_licenses).toEqual(['MIT', 'GPL-2.0-only'])
|
||||
})
|
||||
|
||||
describe('licenses that are not valid SPDX licenses', () => {
|
||||
@@ -230,15 +249,15 @@ describe('licenses that are not valid SPDX licenses', () => {
|
||||
|
||||
test('it raises an error for invalid licenses in allow-licenses', async () => {
|
||||
setInput('allow-licenses', ' BSD, GPL 2')
|
||||
expect(() => {
|
||||
readConfig()
|
||||
}).toThrow('Invalid license(s) in allow-licenses: BSD, GPL 2')
|
||||
await expect(readConfig()).rejects.toThrow(
|
||||
'Invalid license(s) in allow-licenses: BSD,GPL 2'
|
||||
)
|
||||
})
|
||||
|
||||
test('it raises an error for invalid licenses in deny-licenses', async () => {
|
||||
setInput('deny-licenses', ' BSD, GPL 2')
|
||||
expect(() => {
|
||||
readConfig()
|
||||
}).toThrow('Invalid license(s) in deny-licenses: BSD, GPL 2')
|
||||
await expect(readConfig()).rejects.toThrow(
|
||||
'Invalid license(s) in deny-licenses: BSD,GPL 2'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import {RequestError} from '@octokit/request-error'
|
||||
import * as dependencyGraph from '../src/dependency-graph'
|
||||
import * as core from '@actions/core'
|
||||
|
||||
// mock call to core.getInput('repo-token'.. to avoid environment setup - Input required and not supplied: repo-token
|
||||
jest.mock('@actions/core', () => ({
|
||||
getInput: (input: string) => {
|
||||
if (input === 'repo-token') {
|
||||
return 'gh_testtoken'
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
test('it properly catches RequestError type', async () => {
|
||||
const token = core.getInput('repo-token', {required: true})
|
||||
expect(token).toBe('gh_testtoken')
|
||||
|
||||
//Integration test to make an API request using current dependencies and ensure response can parse into RequestError
|
||||
try {
|
||||
await dependencyGraph.compare({
|
||||
owner: 'actions',
|
||||
repo: 'dependency-review-action',
|
||||
baseRef: 'refs/heads/master',
|
||||
headRef: 'refs/heads/master'
|
||||
})
|
||||
} catch (error) {
|
||||
expect(error).toBeInstanceOf(RequestError)
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,2 @@
|
||||
fail_on_severity: critical
|
||||
allow_licenses: []
|
||||
@@ -0,0 +1 @@
|
||||
allow-licenses: MIT, GPL-2.0-only
|
||||
@@ -99,17 +99,6 @@ test('it adds license inside the deny list to forbidden changes', async () => {
|
||||
expect(forbidden.length).toEqual(1)
|
||||
})
|
||||
|
||||
// This is more of a "here's a behavior that might be surprising" than an actual
|
||||
// thing we want in the system. Please remove this test after refactoring.
|
||||
test('it adds all licenses to forbidden changes when allow is provided an empty array', async () => {
|
||||
const changes: Changes = [npmChange, rubyChange]
|
||||
let {forbidden} = await getInvalidLicenseChanges(changes, {
|
||||
allow: [],
|
||||
deny: ['BSD']
|
||||
})
|
||||
expect(forbidden.length).toBe(2)
|
||||
})
|
||||
|
||||
test('it does not add license outside the allow list to forbidden changes if it is in removed changes', async () => {
|
||||
const changes: Changes = [
|
||||
{...npmChange, change_type: 'removed'},
|
||||
|
||||
+11
-2
@@ -21,7 +21,7 @@ inputs:
|
||||
description: The head git ref to be used for this check. Has a default value when the workflow event is `pull_request` or `pull_request_target`. Must be provided otherwise.
|
||||
required: false
|
||||
config-file:
|
||||
description: A filepath to the configuration file for the action.
|
||||
description: A path to the configuration file for the action.
|
||||
required: false
|
||||
allow-licenses:
|
||||
description: Comma-separated list of allowed licenses (e.g. "MIT, GPL 3.0, BSD 2 Clause")
|
||||
@@ -30,7 +30,16 @@ inputs:
|
||||
description: Comma-separated list of forbidden licenses (e.g. "MIT, GPL 3.0, BSD 2 Clause")
|
||||
required: false
|
||||
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")
|
||||
required: false
|
||||
external-repo-token:
|
||||
description: A token for fetching external configuration file if it lives in another repository. It is required if the repository is private
|
||||
required: false
|
||||
license-check:
|
||||
description: A boolean to determine if license checks should be performed
|
||||
required: false
|
||||
vulnerability-check:
|
||||
description: A boolean to determine if vulnerability checks should be performed
|
||||
required: false
|
||||
runs:
|
||||
using: 'node16'
|
||||
|
||||
+20947
-3827
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+3
-234
@@ -1175,240 +1175,9 @@ 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.
|
||||
|
||||
|
||||
lodash.includes
|
||||
lodash
|
||||
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.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/>
|
||||
Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
||||
|
||||
Based on Underscore.js, copyright Jeremy Ashkenas,
|
||||
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
|
||||
@@ -1531,7 +1300,7 @@ octokit
|
||||
MIT
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2018 Octokit contributors
|
||||
Copyright (c) 2023 Octokit 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
|
||||
|
||||
Generated
+612
-947
File diff suppressed because it is too large
Load Diff
+18
-16
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dependency-review-action",
|
||||
"version": "2.5.1",
|
||||
"version": "3.0.2",
|
||||
"private": true,
|
||||
"description": "A GitHub Action for Dependency Review",
|
||||
"main": "lib/main.js",
|
||||
@@ -28,33 +28,35 @@
|
||||
"@actions/core": "^1.10.0",
|
||||
"@actions/github": "^5.1.1",
|
||||
"@octokit/plugin-retry": "^4.0.3",
|
||||
"@octokit/request-error": "^3.0.2",
|
||||
"@octokit/request-error": "^2.1.0",
|
||||
"ansi-styles": "^6.2.1",
|
||||
"got": "^12.5.2",
|
||||
"got": "^12.5.3",
|
||||
"nodemon": "^2.0.20",
|
||||
"octokit": "^2.0.10",
|
||||
"octokit": "^2.0.11",
|
||||
"spdx-expression-parse": "^3.0.1",
|
||||
"spdx-satisfies": "^5.0.1",
|
||||
"yaml": "^2.1.3",
|
||||
"zod": "^3.19.1"
|
||||
"yaml": "^2.2.1",
|
||||
"zod": "^3.20.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/node": "^16.18.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.41.0",
|
||||
"@typescript-eslint/parser": "^5.41.0",
|
||||
"@types/node": "^16.18.11",
|
||||
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||
"@typescript-eslint/parser": "^5.48.0",
|
||||
"@types/spdx-expression-parse": "^3.0.2",
|
||||
"@types/spdx-satisfies": "^0.1.0",
|
||||
"@vercel/ncc": "^0.34.0",
|
||||
"esbuild-register": "^3.3.3",
|
||||
"eslint": "^8.26.0",
|
||||
"eslint-plugin-github": "^4.4.0",
|
||||
"eslint-plugin-jest": "^27.1.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||
"@typescript-eslint/parser": "^5.47.1",
|
||||
"@vercel/ncc": "^0.36.0",
|
||||
"esbuild-register": "^3.4.2",
|
||||
"eslint": "^8.31.0",
|
||||
"eslint-plugin-github": "^4.6.0",
|
||||
"eslint-plugin-jest": "^27.2.1",
|
||||
"jest": "^27.5.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"nodemon": "^2.0.20",
|
||||
"prettier": "2.7.1",
|
||||
"prettier": "2.8.2",
|
||||
"ts-jest": "^27.1.4",
|
||||
"typescript": "^4.8.4"
|
||||
"typescript": "^4.9.4"
|
||||
}
|
||||
}
|
||||
|
||||
+144
-92
@@ -3,15 +3,57 @@ import path from 'path'
|
||||
import YAML from 'yaml'
|
||||
import * as core from '@actions/core'
|
||||
import * as z from 'zod'
|
||||
import {
|
||||
ConfigurationOptions,
|
||||
ConfigurationOptionsSchema,
|
||||
SeveritySchema,
|
||||
SCOPES
|
||||
} from './schemas'
|
||||
import {isSPDXValid} from './utils'
|
||||
import {ConfigurationOptions, ConfigurationOptionsSchema} from './schemas'
|
||||
import {isSPDXValid, octokitClient} from './utils'
|
||||
|
||||
type licenseKey = 'allow-licenses' | 'deny-licenses'
|
||||
type ConfigurationOptionsPartial = Partial<ConfigurationOptions>
|
||||
|
||||
export async function readConfig(): Promise<ConfigurationOptions> {
|
||||
const inlineConfig = readInlineConfig()
|
||||
|
||||
const configFile = getOptionalInput('config-file')
|
||||
if (configFile !== undefined) {
|
||||
const externalConfig = await readConfigFile(configFile)
|
||||
|
||||
return ConfigurationOptionsSchema.parse({
|
||||
...externalConfig,
|
||||
...inlineConfig
|
||||
})
|
||||
}
|
||||
|
||||
return ConfigurationOptionsSchema.parse(inlineConfig)
|
||||
}
|
||||
|
||||
function readInlineConfig(): ConfigurationOptionsPartial {
|
||||
const fail_on_severity = getOptionalInput('fail-on-severity')
|
||||
const fail_on_scopes = parseList(getOptionalInput('fail-on-scopes'))
|
||||
const allow_licenses = parseList(getOptionalInput('allow-licenses'))
|
||||
const deny_licenses = parseList(getOptionalInput('deny-licenses'))
|
||||
const allow_ghsas = parseList(getOptionalInput('allow-ghsas'))
|
||||
const license_check = getOptionalBoolean('license-check')
|
||||
const vulnerability_check = getOptionalBoolean('vulnerability-check')
|
||||
const base_ref = getOptionalInput('base-ref')
|
||||
const head_ref = getOptionalInput('head-ref')
|
||||
|
||||
validateLicenses('allow-licenses', allow_licenses)
|
||||
validateLicenses('deny-licenses', deny_licenses)
|
||||
|
||||
const keys = {
|
||||
fail_on_severity,
|
||||
fail_on_scopes,
|
||||
allow_licenses,
|
||||
deny_licenses,
|
||||
allow_ghsas,
|
||||
license_check,
|
||||
vulnerability_check,
|
||||
base_ref,
|
||||
head_ref
|
||||
}
|
||||
|
||||
return Object.fromEntries(
|
||||
Object.entries(keys).filter(([_, value]) => value !== undefined)
|
||||
)
|
||||
}
|
||||
|
||||
function getOptionalBoolean(name: string): boolean | undefined {
|
||||
const value = core.getInput(name)
|
||||
@@ -32,104 +74,114 @@ function parseList(list: string | undefined): string[] | undefined {
|
||||
}
|
||||
|
||||
function validateLicenses(
|
||||
key: licenseKey,
|
||||
key: 'allow-licenses' | 'deny-licenses',
|
||||
licenses: string[] | undefined
|
||||
): void {
|
||||
if (licenses === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const invalid_licenses = licenses.filter(license => !isSPDXValid(license))
|
||||
|
||||
if (invalid_licenses.length > 0) {
|
||||
throw new Error(`Invalid license(s) in ${key}: ${invalid_licenses}`)
|
||||
}
|
||||
}
|
||||
|
||||
async function readConfigFile(
|
||||
filePath: string
|
||||
): Promise<ConfigurationOptionsPartial> {
|
||||
// match a remote config (e.g. 'owner/repo/filepath@someref')
|
||||
const format = new RegExp(
|
||||
'(?<owner>[^/]+)/(?<repo>[^/]+)/(?<path>[^@]+)@(?<ref>.*)'
|
||||
)
|
||||
|
||||
let data: string
|
||||
const pieces = format.exec(filePath)
|
||||
|
||||
try {
|
||||
if (pieces?.groups && pieces.length === 5) {
|
||||
data = await getRemoteConfig({
|
||||
owner: pieces.groups.owner,
|
||||
repo: pieces.groups.repo,
|
||||
path: pieces.groups.path,
|
||||
ref: pieces.groups.ref
|
||||
})
|
||||
} else {
|
||||
data = fs.readFileSync(path.resolve(filePath), 'utf-8')
|
||||
}
|
||||
return parseConfigFile(data)
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Invalid license(s) in ${key}: ${invalid_licenses.join(', ')}`
|
||||
`Unable to fetch or parse config file: ${(error as Error).message}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export function readConfig(): ConfigurationOptions {
|
||||
const externalConfig = getOptionalInput('config-file')
|
||||
if (externalConfig !== undefined) {
|
||||
const config = readConfigFile(externalConfig)
|
||||
// the reasoning behind reading the inline config when an external
|
||||
// config file is provided is that we still want to allow users to
|
||||
// pass inline options in the presence of an external config file.
|
||||
const inlineConfig = readInlineConfig()
|
||||
// the external config takes precedence
|
||||
return Object.assign({}, inlineConfig, config)
|
||||
} else {
|
||||
return readInlineConfig()
|
||||
}
|
||||
}
|
||||
|
||||
export function readInlineConfig(): ConfigurationOptions {
|
||||
const fail_on_severity = SeveritySchema.parse(
|
||||
getOptionalInput('fail-on-severity')
|
||||
)
|
||||
const fail_on_scopes = z
|
||||
.array(z.enum(SCOPES))
|
||||
.default(['runtime'])
|
||||
.parse(parseList(getOptionalInput('fail-on-scopes')))
|
||||
|
||||
const allow_licenses = parseList(getOptionalInput('allow-licenses'))
|
||||
const deny_licenses = parseList(getOptionalInput('deny-licenses'))
|
||||
|
||||
if (allow_licenses !== undefined && deny_licenses !== undefined) {
|
||||
throw new Error("Can't specify both allow_licenses and deny_licenses")
|
||||
}
|
||||
validateLicenses('allow-licenses', allow_licenses)
|
||||
validateLicenses('deny-licenses', deny_licenses)
|
||||
|
||||
const allow_ghsas = parseList(getOptionalInput('allow-ghsas'))
|
||||
|
||||
const license_check = z
|
||||
.boolean()
|
||||
.default(true)
|
||||
.parse(getOptionalBoolean('license-check'))
|
||||
const vulnerability_check = z
|
||||
.boolean()
|
||||
.default(true)
|
||||
.parse(getOptionalBoolean('vulnerability-check'))
|
||||
if (license_check === false && vulnerability_check === false) {
|
||||
throw new Error("Can't disable both license-check and vulnerability-check")
|
||||
}
|
||||
|
||||
const base_ref = getOptionalInput('base-ref')
|
||||
const head_ref = getOptionalInput('head-ref')
|
||||
|
||||
return {
|
||||
fail_on_severity,
|
||||
fail_on_scopes,
|
||||
allow_licenses,
|
||||
deny_licenses,
|
||||
allow_ghsas,
|
||||
license_check,
|
||||
vulnerability_check,
|
||||
base_ref,
|
||||
head_ref
|
||||
}
|
||||
}
|
||||
|
||||
export function readConfigFile(filePath: string): ConfigurationOptions {
|
||||
let data
|
||||
|
||||
function parseConfigFile(configData: string): ConfigurationOptionsPartial {
|
||||
try {
|
||||
data = fs.readFileSync(path.resolve(filePath), 'utf-8')
|
||||
} catch (error: unknown) {
|
||||
const data = YAML.parse(configData)
|
||||
|
||||
// These are the options that we support where the user can provide
|
||||
// either a YAML list or a comma-separated string.
|
||||
const listKeys = [
|
||||
'allow-licenses',
|
||||
'deny-licenses',
|
||||
'fail-on-scopes',
|
||||
'allow-ghsas'
|
||||
]
|
||||
|
||||
for (const key of Object.keys(data)) {
|
||||
// strings can contain list values (e.g. 'MIT, Apache-2.0'). In this
|
||||
// case we need to parse that into a list (e.g. ['MIT', 'Apache-2.0']).
|
||||
if (listKeys.includes(key)) {
|
||||
const val = data[key]
|
||||
|
||||
if (typeof val === 'string') {
|
||||
data[key] = val.split(',').map(x => x.trim())
|
||||
}
|
||||
}
|
||||
|
||||
// perform SPDX validation
|
||||
if (key === 'allow-licenses' || key === 'deny-licenses') {
|
||||
validateLicenses(key, data[key])
|
||||
}
|
||||
|
||||
// get rid of the ugly dashes from the actions conventions
|
||||
if (key.includes('-')) {
|
||||
data[key.replace(/-/g, '_')] = data[key]
|
||||
delete data[key]
|
||||
}
|
||||
}
|
||||
return data
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
data = YAML.parse(data)
|
||||
|
||||
for (const key of Object.keys(data)) {
|
||||
if (key === 'allow-licenses' || key === 'deny-licenses') {
|
||||
validateLicenses(key, data[key])
|
||||
}
|
||||
// get rid of the ugly dashes from the actions conventions
|
||||
if (key.includes('-')) {
|
||||
data[key.replace(/-/g, '_')] = data[key]
|
||||
delete data[key]
|
||||
}
|
||||
}
|
||||
const values = ConfigurationOptionsSchema.parse(data)
|
||||
return values
|
||||
}
|
||||
|
||||
async function getRemoteConfig(configOpts: {
|
||||
[key: string]: string
|
||||
}): Promise<string> {
|
||||
try {
|
||||
const {data} = await octokitClient(
|
||||
'external-repo-token',
|
||||
false
|
||||
).rest.repos.getContent({
|
||||
mediaType: {
|
||||
format: 'raw'
|
||||
},
|
||||
owner: configOpts.owner,
|
||||
repo: configOpts.repo,
|
||||
path: configOpts.path,
|
||||
ref: configOpts.ref
|
||||
})
|
||||
|
||||
// When using mediaType.format = 'raw', the response.data is a string
|
||||
// but this is not reflected in the return type of getContent, so we're
|
||||
// casting the return value to a string.
|
||||
return z.string().parse(data as unknown)
|
||||
} catch (error) {
|
||||
core.debug(error as string)
|
||||
throw new Error('Error fetching remote config file')
|
||||
}
|
||||
}
|
||||
|
||||
+5
-8
@@ -1,8 +1,6 @@
|
||||
import * as core from '@actions/core'
|
||||
import spdxSatisfies from 'spdx-satisfies'
|
||||
import {Octokit} from 'octokit'
|
||||
import {Change, Changes} from './schemas'
|
||||
import {isSPDXValid} from './utils'
|
||||
import {isSPDXValid, octokitClient} from './utils'
|
||||
|
||||
/**
|
||||
* Loops through a list of changes, filtering and returning the
|
||||
@@ -76,12 +74,11 @@ const fetchGHLicense = async (
|
||||
owner: string,
|
||||
repo: string
|
||||
): Promise<string | null> => {
|
||||
const octokit = new Octokit({
|
||||
auth: core.getInput('repo-token', {required: true})
|
||||
})
|
||||
|
||||
try {
|
||||
const response = await octokit.rest.licenses.getForRepo({owner, repo})
|
||||
const response = await octokitClient().rest.licenses.getForRepo({
|
||||
owner,
|
||||
repo
|
||||
})
|
||||
return response.data.license?.spdx_id ?? null
|
||||
} catch (_) {
|
||||
return null
|
||||
|
||||
+3
-3
@@ -18,7 +18,7 @@ import {groupDependenciesByManifest} from './utils'
|
||||
|
||||
async function run(): Promise<void> {
|
||||
try {
|
||||
const config = readConfig()
|
||||
const config = await readConfig()
|
||||
const refs = getRefs(config, github.context)
|
||||
|
||||
const changes = await dependencyGraph.compare({
|
||||
@@ -28,7 +28,7 @@ async function run(): Promise<void> {
|
||||
headRef: refs.head
|
||||
})
|
||||
|
||||
const minSeverity = config.fail_on_severity as Severity
|
||||
const minSeverity = config.fail_on_severity
|
||||
const scopedChanges = filterChangesByScopes(config.fail_on_scopes, changes)
|
||||
const filteredChanges = filterAllowedAdvisories(
|
||||
config.allow_ghsas,
|
||||
@@ -76,7 +76,7 @@ async function run(): Promise<void> {
|
||||
)
|
||||
} else if (error instanceof RequestError && error.status === 403) {
|
||||
core.setFailed(
|
||||
`Dependency review is not supported on this repository. Please ensure that Dependency graph is enabled, see https://github.com/${github.context.repo.owner}/${github.context.repo.repo}/settings/security_analysis`
|
||||
`Dependency review is not supported on this repository. Please ensure that Dependency graph is enabled along with GitHub Advanced Security on private repositories, see https://github.com/${github.context.repo.owner}/${github.context.repo.repo}/settings/security_analysis`
|
||||
)
|
||||
} else {
|
||||
if (error instanceof Error) {
|
||||
|
||||
+29
-11
@@ -38,20 +38,38 @@ export const ConfigurationOptionsSchema = z
|
||||
.object({
|
||||
fail_on_severity: SeveritySchema,
|
||||
fail_on_scopes: z.array(z.enum(SCOPES)).default(['runtime']),
|
||||
allow_licenses: z.array(z.string()).default([]),
|
||||
deny_licenses: z.array(z.string()).default([]),
|
||||
allow_licenses: z.array(z.string()).optional(),
|
||||
deny_licenses: z.array(z.string()).optional(),
|
||||
allow_ghsas: z.array(z.string()).default([]),
|
||||
license_check: z.boolean().default(true),
|
||||
vulnerability_check: z.boolean().default(true),
|
||||
config_file: z.string().optional().default('false'),
|
||||
base_ref: z.string(),
|
||||
head_ref: z.string()
|
||||
config_file: z.string().optional(),
|
||||
base_ref: z.string().optional(),
|
||||
head_ref: z.string().optional()
|
||||
})
|
||||
.superRefine((config, context) => {
|
||||
if (config.allow_licenses && config.deny_licenses) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: 'You cannot specify both allow-licenses and deny-licenses'
|
||||
})
|
||||
}
|
||||
if (config.allow_licenses && config.allow_licenses.length < 1) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: 'You should provide at least one license in allow-licenses'
|
||||
})
|
||||
}
|
||||
if (
|
||||
config.license_check === false &&
|
||||
config.vulnerability_check === false
|
||||
) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: "Can't disable both license-check and vulnerability-check"
|
||||
})
|
||||
}
|
||||
})
|
||||
.partial()
|
||||
.refine(
|
||||
obj => !(obj.allow_licenses && obj.deny_licenses),
|
||||
'Your workflow file has both an allow_licenses list and deny_licenses list, but you can only set one or the other.'
|
||||
)
|
||||
|
||||
export const ChangesSchema = z.array(ChangeSchema)
|
||||
|
||||
@@ -59,4 +77,4 @@ export type Change = z.infer<typeof ChangeSchema>
|
||||
export type Changes = z.infer<typeof ChangesSchema>
|
||||
export type ConfigurationOptions = z.infer<typeof ConfigurationOptionsSchema>
|
||||
export type Severity = z.infer<typeof SeveritySchema>
|
||||
export type Scope = typeof SCOPES[number]
|
||||
export type Scope = (typeof SCOPES)[number]
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ export function addChangeVulnerabilitiesToSummary(
|
||||
core.summary
|
||||
.addHeading('Vulnerabilities')
|
||||
.addQuote(
|
||||
`Vulnerabilites were filtered by mininum severity <strong>${severity}</strong>.`
|
||||
`Vulnerabilities were filtered by minimum severity <strong>${severity}</strong>.`
|
||||
)
|
||||
|
||||
if (addedPackages.length === 0) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import * as core from '@actions/core'
|
||||
import {Octokit} from 'octokit'
|
||||
import spdxParse from 'spdx-expression-parse'
|
||||
import {Changes} from './schemas'
|
||||
|
||||
@@ -38,3 +40,29 @@ export function isSPDXValid(license: string): boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function isEnterprise(): boolean {
|
||||
const serverUrl = new URL(
|
||||
process.env['GITHUB_SERVER_URL'] ?? 'https://github.com'
|
||||
)
|
||||
return serverUrl.hostname.toLowerCase() !== 'github.com'
|
||||
}
|
||||
|
||||
export function octokitClient(token = 'repo-token', required = true): Octokit {
|
||||
const opts: Record<string, unknown> = {}
|
||||
|
||||
// auth is only added if token is present. For remote config files in public
|
||||
// repos the token is optional, so it could be undefined.
|
||||
const auth = core.getInput(token, {required})
|
||||
if (auth !== undefined) {
|
||||
opts['auth'] = auth
|
||||
}
|
||||
|
||||
//baseUrl is required for GitHub Enterprise Server
|
||||
//https://github.com/octokit/octokit.js/blob/9c8fa89d5b0bc4ddbd6dec638db00a2f6c94c298/README.md?plain=1#L196
|
||||
if (isEnterprise()) {
|
||||
opts['baseUrl'] = new URL('api/v3', process.env['GITHUB_SERVER_URL'])
|
||||
}
|
||||
|
||||
return new Octokit(opts)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user