feat: add the ability to run with '--json' and output the result (#78)
* addition-of-json-flag * Set output of npn audit
This commit is contained in:
@@ -24,6 +24,7 @@ If vulnerabilities are found by `npm audit`, Action triggered by push, schedule
|
||||
|:--:|:--:|:--:|:--|
|
||||
|audit_level|false|low|The value of `--audit-level` flag|
|
||||
|production_flag|false|false|Runnning `npm audit` with `--production`|
|
||||
|json_flag|false|false|Runnning `npm audit` with `--json`|
|
||||
|issue_assignees|false|N/A|Issue assignees (separated by commma)|
|
||||
|issue_labels|false|N/A|Issue labels (separated by commma)|
|
||||
|issue_title|false|npm audit found vulnerabilities|Issue title|
|
||||
@@ -33,7 +34,9 @@ If vulnerabilities are found by `npm audit`, Action triggered by push, schedule
|
||||
|
||||
### Outputs
|
||||
|
||||
N/A
|
||||
|Parameter name|Description|
|
||||
|:--:|:--|
|
||||
|npm_audit|The output of the npm audit report in a text format|
|
||||
|
||||
## Example Workflow
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ describe('run', () => {
|
||||
}
|
||||
})
|
||||
|
||||
audit.run('low', 'false')
|
||||
audit.run('low', 'false', 'false')
|
||||
expect(audit.foundVulnerability()).toBeTruthy()
|
||||
})
|
||||
|
||||
@@ -51,7 +51,28 @@ describe('run', () => {
|
||||
}
|
||||
})
|
||||
|
||||
audit.run('low', 'true')
|
||||
audit.run('low', 'true', 'false')
|
||||
expect(audit.foundVulnerability()).toBeTruthy()
|
||||
})
|
||||
|
||||
test('finds vulnerabilities with json flag enabled', () => {
|
||||
mocked(child_process).spawnSync.mockImplementation((): any => {
|
||||
const stdout = fs.readFileSync(
|
||||
path.join(__dirname, 'testdata/audit/error.json')
|
||||
)
|
||||
|
||||
return {
|
||||
pid: 100,
|
||||
output: [stdout],
|
||||
stdout,
|
||||
stderr: '',
|
||||
status: 1,
|
||||
signal: null,
|
||||
error: null
|
||||
}
|
||||
})
|
||||
|
||||
audit.run('low', 'false', 'true')
|
||||
expect(audit.foundVulnerability()).toBeTruthy()
|
||||
})
|
||||
|
||||
@@ -72,7 +93,7 @@ describe('run', () => {
|
||||
}
|
||||
})
|
||||
|
||||
audit.run('low', 'false')
|
||||
audit.run('low', 'false', 'false')
|
||||
expect(audit.foundVulnerability()).toBeFalsy()
|
||||
})
|
||||
|
||||
@@ -91,7 +112,7 @@ describe('run', () => {
|
||||
|
||||
expect.assertions(1)
|
||||
const e = new Error('Something is wrong')
|
||||
expect(() => audit.run('low', 'false')).toThrowError(e)
|
||||
expect(() => audit.run('low', 'false', 'false')).toThrowError(e)
|
||||
})
|
||||
|
||||
test('throws an error if status is null', () => {
|
||||
@@ -109,7 +130,7 @@ describe('run', () => {
|
||||
|
||||
expect.assertions(1)
|
||||
const e = new Error('the subprocess terminated due to a signal.')
|
||||
expect(() => audit.run('low', 'false')).toThrowError(e)
|
||||
expect(() => audit.run('low', 'false', 'false')).toThrowError(e)
|
||||
})
|
||||
|
||||
test('throws an error if stderr is null', () => {
|
||||
@@ -127,6 +148,6 @@ describe('run', () => {
|
||||
|
||||
expect.assertions(1)
|
||||
const e = new Error('Something is wrong')
|
||||
expect(() => audit.run('low', 'false')).toThrowError(e)
|
||||
expect(() => audit.run('low', 'false', 'false')).toThrowError(e)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -16,6 +16,7 @@ describe('run', () => {
|
||||
|
||||
process.env.INPUT_AUDIT_LEVEL = 'low'
|
||||
process.env.INPUT_PRODUCTION_FLAG = 'false'
|
||||
process.env.INPUT_JSON_FLAG = 'false'
|
||||
process.env.INPUT_GITHUB_CONTEXT =
|
||||
'{ "event_name": "pull_request", "event": { "number": 100} }'
|
||||
process.env.INPUT_GITHUB_TOKEN = '***'
|
||||
|
||||
73
__tests__/testdata/audit/error.json
vendored
Normal file
73
__tests__/testdata/audit/error.json
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"actions": [
|
||||
{
|
||||
"isMajor": false,
|
||||
"action": "install",
|
||||
"resolves": [
|
||||
{
|
||||
"id": 532,
|
||||
"path": "moment",
|
||||
"dev": false,
|
||||
"optional": false,
|
||||
"bundled": false
|
||||
}
|
||||
],
|
||||
"module": "moment",
|
||||
"target": "2.29.1"
|
||||
}
|
||||
],
|
||||
"advisories": {
|
||||
"532": {
|
||||
"findings": [
|
||||
{
|
||||
"version": "2.19.2",
|
||||
"paths": [
|
||||
"moment"
|
||||
]
|
||||
}
|
||||
],
|
||||
"id": 532,
|
||||
"created": "2017-09-21T20:40:00.889Z",
|
||||
"updated": "2019-06-24T15:10:05.868Z",
|
||||
"deleted": null,
|
||||
"title": "Regular Expression Denial of Service",
|
||||
"found_by": {
|
||||
"name": "Cristian-Alexandru Staicu"
|
||||
},
|
||||
"reported_by": {
|
||||
"name": "Cristian-Alexandru Staicu"
|
||||
},
|
||||
"module_name": "moment",
|
||||
"cves": [],
|
||||
"vulnerable_versions": "<2.19.3",
|
||||
"patched_versions": ">=2.19.3",
|
||||
"overview": "Affected versions of `moment` are vulnerable to a low severity regular expression denial of service when parsing dates as strings.",
|
||||
"recommendation": "Update to version 2.19.3 or later.",
|
||||
"references": "- [Issue #4163](https://github.com/moment/moment/issues/4163)\n- [PR #4326](https://github.com/moment/moment/pull/4326)",
|
||||
"access": "public",
|
||||
"severity": "low",
|
||||
"cwe": "CWE-400",
|
||||
"metadata": {
|
||||
"module_type": "",
|
||||
"exploitability": 5,
|
||||
"affected_components": ""
|
||||
},
|
||||
"url": "https://npmjs.com/advisories/532"
|
||||
}
|
||||
},
|
||||
"muted": [],
|
||||
"metadata": {
|
||||
"vulnerabilities": {
|
||||
"info": 0,
|
||||
"low": 7,
|
||||
"moderate": 1,
|
||||
"high": 5,
|
||||
"critical": 0
|
||||
},
|
||||
"dependencies": 659,
|
||||
"devDependencies": 0,
|
||||
"optionalDependencies": 0,
|
||||
"totalDependencies": 659
|
||||
},
|
||||
"runId": "88c86b12-b4a4-4827-9d3c-d58ae74384c5"
|
||||
}
|
||||
@@ -10,6 +10,10 @@ inputs:
|
||||
description: 'Run npm audit with --production'
|
||||
default: 'false'
|
||||
required: false
|
||||
json_flag:
|
||||
description: 'Run npm audit with --json'
|
||||
default: 'false'
|
||||
required: false
|
||||
github_context:
|
||||
description: 'The `github` context'
|
||||
default: ${{ toJson(github) }}
|
||||
@@ -34,6 +38,9 @@ inputs:
|
||||
description: 'Flag to de-dupe against open issues'
|
||||
default: 'false'
|
||||
required: false
|
||||
outputs:
|
||||
npm_audit:
|
||||
description: 'The output of the npm audit report in a text format'
|
||||
runs:
|
||||
using: 'node12'
|
||||
main: 'dist/index.js'
|
||||
|
||||
9
dist/index.js
vendored
9
dist/index.js
vendored
@@ -556,12 +556,15 @@ class Audit {
|
||||
this.stdout = '';
|
||||
this.status = null;
|
||||
}
|
||||
run(auditLevel, productionFlag) {
|
||||
run(auditLevel, productionFlag, jsonFlag) {
|
||||
try {
|
||||
const auditOptions = ['audit', '--audit-level', auditLevel];
|
||||
if (productionFlag === 'true') {
|
||||
auditOptions.push('--production');
|
||||
}
|
||||
if (jsonFlag === 'true') {
|
||||
auditOptions.push('--json');
|
||||
}
|
||||
const result = child_process_1.spawnSync('npm', auditOptions, {
|
||||
encoding: 'utf-8',
|
||||
maxBuffer: SPAWN_PROCESS_BUFFER_SIZE
|
||||
@@ -1435,6 +1438,10 @@ function run() {
|
||||
if (!['true', 'false'].includes(productionFlag)) {
|
||||
throw new Error('Invalid input: production_flag');
|
||||
}
|
||||
const jsonFlag = core.getInput('json_flag', { required: false });
|
||||
if (!['true', 'false'].includes(jsonFlag)) {
|
||||
throw new Error('Invalid input: json_flag');
|
||||
}
|
||||
// run `npm audit`
|
||||
const audit = new audit_1.Audit();
|
||||
audit.run(auditLevel, productionFlag);
|
||||
|
||||
@@ -7,7 +7,7 @@ export class Audit {
|
||||
stdout = ''
|
||||
private status: number | null = null
|
||||
|
||||
public run(auditLevel: string, productionFlag: string): void {
|
||||
public run(auditLevel: string, productionFlag: string, jsonFlag: string): void {
|
||||
try {
|
||||
const auditOptions: Array<string> = ['audit', '--audit-level', auditLevel]
|
||||
|
||||
@@ -15,6 +15,10 @@ export class Audit {
|
||||
auditOptions.push('--production')
|
||||
}
|
||||
|
||||
if (jsonFlag === 'true') {
|
||||
auditOptions.push('--json')
|
||||
}
|
||||
|
||||
const result: SpawnSyncReturns<string> = spawnSync('npm', auditOptions, {
|
||||
encoding: 'utf-8',
|
||||
maxBuffer: SPAWN_PROCESS_BUFFER_SIZE
|
||||
|
||||
@@ -30,10 +30,17 @@ export async function run(): Promise<void> {
|
||||
throw new Error('Invalid input: production_flag')
|
||||
}
|
||||
|
||||
const jsonFlag = core.getInput('json_flag', {required: false})
|
||||
if (!['true', 'false'].includes(jsonFlag)) {
|
||||
throw new Error('Invalid input: json_flag')
|
||||
}
|
||||
|
||||
|
||||
// run `npm audit`
|
||||
const audit = new Audit()
|
||||
audit.run(auditLevel, productionFlag)
|
||||
audit.run(auditLevel, productionFlag, jsonFlag)
|
||||
core.info(audit.stdout)
|
||||
core.setOutput('npm_audit', audit.stdout);
|
||||
|
||||
if (audit.foundVulnerability()) {
|
||||
// vulnerabilities are found
|
||||
|
||||
Reference in New Issue
Block a user