diff --git a/README.md b/README.md index 9ef8ca7..07baa82 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ If vulnerabilities are found by `npm audit`, Action triggered by push, schedule |Parameter|Required|Default Value|Description| |:--:|:--:|:--:|:--| |audit_level|false|low|The value of `--audit-level` flag| +|production_flag|false|false|Runnning `npm audit` with `--production`| |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| diff --git a/__tests__/audit.test.ts b/__tests__/audit.test.ts index 2bf4654..ebca734 100644 --- a/__tests__/audit.test.ts +++ b/__tests__/audit.test.ts @@ -13,7 +13,7 @@ describe('run', () => { mocked(child_process).spawnSync.mockClear() }) - test('finds vulnerabilities', () => { + test('finds vulnerabilities with default values', () => { mocked(child_process).spawnSync.mockImplementation((): any => { const stdout = fs.readFileSync( path.join(__dirname, 'testdata/audit/error.txt') @@ -30,7 +30,28 @@ describe('run', () => { } }) - audit.run('low') + audit.run('low', 'false') + expect(audit.foundVulnerability()).toBeTruthy() + }) + + test('finds vulnerabilities with production flag enabled', () => { + mocked(child_process).spawnSync.mockImplementation((): any => { + const stdout = fs.readFileSync( + path.join(__dirname, 'testdata/audit/error.txt') + ) + + return { + pid: 100, + output: [stdout], + stdout, + stderr: '', + status: 1, + signal: null, + error: null + } + }) + + audit.run('low', 'true') expect(audit.foundVulnerability()).toBeTruthy() }) @@ -51,7 +72,7 @@ describe('run', () => { } }) - audit.run('low') + audit.run('low', 'false') expect(audit.foundVulnerability()).toBeFalsy() }) @@ -70,7 +91,7 @@ describe('run', () => { expect.assertions(1) const e = new Error('Something is wrong') - expect(() => audit.run('low')).toThrowError(e) + expect(() => audit.run('low', 'false')).toThrowError(e) }) test('throws an error if status is null', () => { @@ -88,7 +109,7 @@ describe('run', () => { expect.assertions(1) const e = new Error('the subprocess terminated due to a signal.') - expect(() => audit.run('low')).toThrowError(e) + expect(() => audit.run('low', 'false')).toThrowError(e) }) test('throws an error if stderr is null', () => { @@ -106,6 +127,6 @@ describe('run', () => { expect.assertions(1) const e = new Error('Something is wrong') - expect(() => audit.run('low')).toThrowError(e) + expect(() => audit.run('low', 'false')).toThrowError(e) }) }) diff --git a/__tests__/main.test.ts b/__tests__/main.test.ts index 5adc670..e8b6916 100644 --- a/__tests__/main.test.ts +++ b/__tests__/main.test.ts @@ -15,6 +15,7 @@ describe('run', () => { mocked(pr).createComment.mockClear() process.env.INPUT_AUDIT_LEVEL = 'low' + process.env.INPUT_PRODUCTION_FLAG = 'false' process.env.INPUT_GITHUB_CONTEXT = '{ "event_name": "pull_request", "event": { "number": 100} }' process.env.INPUT_GITHUB_TOKEN = '***' diff --git a/__tests__/testdata/workdir/package-lock.json b/__tests__/testdata/workdir/package-lock.json index 0fe7392..388db15 100644 --- a/__tests__/testdata/workdir/package-lock.json +++ b/__tests__/testdata/workdir/package-lock.json @@ -355,6 +355,12 @@ "mime-types": "~2.1.24" } }, + "typescript": { + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", + "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", + "dev": true + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/__tests__/testdata/workdir/package.json b/__tests__/testdata/workdir/package.json index 7c65e9b..0a0a10a 100644 --- a/__tests__/testdata/workdir/package.json +++ b/__tests__/testdata/workdir/package.json @@ -11,5 +11,8 @@ "license": "ISC", "dependencies": { "express": "^4.17.1" + }, + "devDependencies": { + "typescript": "^3.9.7" } } diff --git a/action.yml b/action.yml index 09a1f8f..6d6f0b5 100644 --- a/action.yml +++ b/action.yml @@ -6,6 +6,10 @@ inputs: description: 'The value of `--audit-level` flag' default: low required: false + production_flag: + description: 'Run npm audit with --production' + default: 'false' + required: false github_context: description: 'The `github` context' default: ${{ toJson(github) }} diff --git a/src/audit.ts b/src/audit.ts index bd05b0d..1d46b7b 100644 --- a/src/audit.ts +++ b/src/audit.ts @@ -7,11 +7,17 @@ export class Audit { stdout = '' private status: number | null = null - public run(auditLevel: string): void { + public run(auditLevel: string, productionFlag: string): void { try { + const auditOptions: Array =['audit', '--audit-level', auditLevel]; + + if(productionFlag === 'true') { + auditOptions.push('--production'); + } + const result: SpawnSyncReturns = spawnSync( 'npm', - ['audit', '--audit-level', auditLevel], + auditOptions, { encoding: 'utf-8', maxBuffer: SPAWN_PROCESS_BUFFER_SIZE diff --git a/src/main.ts b/src/main.ts index 1d7f68c..36abfe0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -25,9 +25,14 @@ export async function run(): Promise { throw new Error('Invalid input: audit_level') } + const productionFlag = core.getInput('production_flag', {required: false}); + if (!['true', 'false'].includes(productionFlag)) { + throw new Error('Invalid input: production_flag') + } + // run `npm audit` const audit = new Audit() - audit.run(auditLevel) + audit.run(auditLevel, productionFlag) core.info(audit.stdout) if (audit.foundVulnerability()) {