2019-12-08 19:17:13 +09:00
|
|
|
import * as core from '@actions/core'
|
2019-12-09 08:51:14 +09:00
|
|
|
import * as github from '@actions/github'
|
2020-03-14 18:04:03 +09:00
|
|
|
import {Octokit} from '@octokit/rest'
|
2019-12-09 12:43:13 +09:00
|
|
|
import {Audit} from './audit'
|
2019-12-09 22:49:41 +09:00
|
|
|
import {IssueOption} from './interface'
|
2019-12-13 12:18:28 +09:00
|
|
|
import * as issue from './issue'
|
|
|
|
|
import * as pr from './pr'
|
2020-05-23 15:59:51 +09:00
|
|
|
import * as workdir from './workdir'
|
2019-12-08 19:17:13 +09:00
|
|
|
|
2019-12-13 12:18:28 +09:00
|
|
|
export async function run(): Promise<void> {
|
2019-12-08 19:17:13 +09:00
|
|
|
try {
|
2020-05-23 15:59:51 +09:00
|
|
|
// move to working directory
|
|
|
|
|
const workingDirectory = core.getInput('working_directory')
|
|
|
|
|
if (workingDirectory) {
|
|
|
|
|
if (!workdir.isValid(workingDirectory)) {
|
|
|
|
|
throw new Error('Invalid input: working_directory')
|
|
|
|
|
}
|
|
|
|
|
process.chdir(workingDirectory)
|
|
|
|
|
}
|
|
|
|
|
core.info(`Current working directory: ${process.cwd()}`)
|
|
|
|
|
|
2020-03-21 07:08:53 +09:00
|
|
|
// get audit-level
|
|
|
|
|
const auditLevel = core.getInput('audit_level', {required: true})
|
|
|
|
|
if (!['critical', 'high', 'moderate', 'low'].includes(auditLevel)) {
|
|
|
|
|
throw new Error('Invalid input: audit_level')
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-12 10:45:24 +00:00
|
|
|
const productionFlag = core.getInput('production_flag', {required: false})
|
2020-11-12 12:33:56 +02:00
|
|
|
if (!['true', 'false'].includes(productionFlag)) {
|
|
|
|
|
throw new Error('Invalid input: production_flag')
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-12 13:56:05 +02:00
|
|
|
const jsonFlag = core.getInput('json_flag', {required: false})
|
|
|
|
|
if (!['true', 'false'].includes(jsonFlag)) {
|
|
|
|
|
throw new Error('Invalid input: json_flag')
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-13 12:18:28 +09:00
|
|
|
// run `npm audit`
|
2019-12-09 12:43:13 +09:00
|
|
|
const audit = new Audit()
|
2020-12-12 13:56:05 +02:00
|
|
|
audit.run(auditLevel, productionFlag, jsonFlag)
|
2019-12-09 12:43:13 +09:00
|
|
|
core.info(audit.stdout)
|
2020-12-12 12:01:55 +00:00
|
|
|
core.setOutput('npm_audit', audit.stdout)
|
2019-12-08 22:10:35 +09:00
|
|
|
|
2019-12-13 12:18:28 +09:00
|
|
|
if (audit.foundVulnerability()) {
|
|
|
|
|
// vulnerabilities are found
|
2019-12-08 22:10:35 +09:00
|
|
|
|
2019-12-13 12:18:28 +09:00
|
|
|
// get GitHub information
|
|
|
|
|
const ctx = JSON.parse(core.getInput('github_context'))
|
|
|
|
|
const token: string = core.getInput('github_token', {required: true})
|
2020-05-23 14:46:31 +09:00
|
|
|
const octokit = new Octokit({
|
|
|
|
|
auth: token
|
|
|
|
|
})
|
2019-12-09 08:51:14 +09:00
|
|
|
|
2019-12-13 12:18:28 +09:00
|
|
|
if (ctx.event_name === 'pull_request') {
|
2021-10-03 09:26:16 +09:00
|
|
|
const createPRComments = core.getInput('create_pr_comments')
|
|
|
|
|
if (!['true', 'false'].includes(createPRComments)) {
|
|
|
|
|
throw new Error('Invalid input: create_pr_comments')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (createPRComments === 'true') {
|
|
|
|
|
await pr.createComment(
|
|
|
|
|
token,
|
|
|
|
|
github.context.repo.owner,
|
|
|
|
|
github.context.repo.repo,
|
|
|
|
|
ctx.event.number,
|
|
|
|
|
audit.strippedStdout()
|
|
|
|
|
)
|
|
|
|
|
}
|
2019-12-13 12:18:28 +09:00
|
|
|
core.setFailed('This repo has some vulnerabilities')
|
|
|
|
|
return
|
|
|
|
|
} else {
|
|
|
|
|
core.debug('open an issue')
|
2021-10-03 09:26:16 +09:00
|
|
|
const createIssues = core.getInput('create_issues')
|
|
|
|
|
if (!['true', 'false'].includes(createIssues)) {
|
|
|
|
|
throw new Error('Invalid input: create_issues')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (createIssues === 'false') {
|
|
|
|
|
core.setFailed('This repo has some vulnerabilities')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-13 12:18:28 +09:00
|
|
|
// remove control characters and create a code block
|
|
|
|
|
const issueBody = audit.strippedStdout()
|
|
|
|
|
const option: IssueOption = issue.getIssueOption(issueBody)
|
2020-05-27 15:18:45 -07:00
|
|
|
|
|
|
|
|
const existingIssueNumber =
|
|
|
|
|
core.getInput('dedupe_issues') === 'true'
|
|
|
|
|
? await issue.getExistingIssueNumber(
|
2021-10-09 12:22:18 +09:00
|
|
|
octokit.rest.issues.listForRepo,
|
2020-05-27 15:18:45 -07:00
|
|
|
github.context.repo
|
|
|
|
|
)
|
|
|
|
|
: null
|
|
|
|
|
|
|
|
|
|
if (existingIssueNumber !== null) {
|
2021-10-09 12:22:18 +09:00
|
|
|
const {data: createdComment} =
|
|
|
|
|
await octokit.rest.issues.createComment({
|
|
|
|
|
...github.context.repo,
|
|
|
|
|
issue_number: existingIssueNumber,
|
|
|
|
|
body: option.body
|
|
|
|
|
})
|
2020-05-27 15:18:45 -07:00
|
|
|
core.debug(`comment ${createdComment.url}`)
|
|
|
|
|
} else {
|
2021-10-09 12:22:18 +09:00
|
|
|
const {data: createdIssue} = await octokit.rest.issues.create({
|
2020-05-27 15:18:45 -07:00
|
|
|
...github.context.repo,
|
|
|
|
|
...option
|
|
|
|
|
})
|
|
|
|
|
core.debug(`#${createdIssue.number}`)
|
|
|
|
|
}
|
2020-01-09 18:59:40 +09:00
|
|
|
core.setFailed('This repo has some vulnerabilities')
|
2019-12-13 12:18:28 +09:00
|
|
|
}
|
|
|
|
|
}
|
2019-12-08 19:17:13 +09:00
|
|
|
} catch (error) {
|
|
|
|
|
core.setFailed(error.message)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run()
|