From cdf0a8f7d709ea6e60290d2b0f0cf2aac9e7d639 Mon Sep 17 00:00:00 2001 From: Tobias Wochinger Date: Fri, 24 Apr 2020 12:15:26 +0200 Subject: [PATCH 1/2] check if issue with this content already exists --- src/index.ts | 4 ++-- src/issue.ts | 43 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/index.ts b/src/index.ts index ed6dfaa..c5551f0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ import * as core from '@actions/core'; import { Trivy, Downloader } from './trivy'; -import { createIssue } from './issue'; +import { getExistingOrCreateIssue } from './issue'; import { TrivyOption, IssueOption, @@ -69,7 +69,7 @@ async function run() { .split(','), }; const token: string = core.getInput('token', { required: true }); - const output: IssueResponse = await createIssue(token, issueOption); + const output: IssueResponse = await getExistingOrCreateIssue(token, issueOption); core.setOutput('html_url', output.htmlUrl); core.setOutput('issue_number', output.issueNumber.toString()); } catch (error) { diff --git a/src/issue.ts b/src/issue.ts index 1d38f1e..a91e3e9 100644 --- a/src/issue.ts +++ b/src/issue.ts @@ -1,11 +1,26 @@ import { Octokit } from '@octokit/rest'; +import * as core from '@actions/core'; import * as github from '@actions/github'; import { IssueOption, IssueResponse } from './interface'; -export async function createIssue( +async function get_trivy_issues(repository: string, token: string) { + const client: Octokit = new Octokit({ auth: token }); + + let trivyIssues = await client.issues.list( + { state: "open", labels: "tool:trivy" , filter: "all" }) + + trivyIssues = trivyIssues.data.filter(issue => issue.repository.full_name == repository) + + core.info(`Found ${trivyIssues.length} open trivy issues for this repository.`) + core.exportVariable('issues', trivyIssues); + + return trivyIssues +} + +async function createIssue( token: string, options: IssueOption -): Promise { +): Promise { const client: Octokit = new Octokit({ auth: token }); const { data: issue, @@ -15,9 +30,33 @@ export async function createIssue( ...options, } ); + return issue +} + +export async function getExistingOrCreateIssue( + token: string, + options: IssueOption +): Promise { + const currentVulnerability = options.body.match(/\|CVE-[0-9-]+\|/) + core.info(`Current vulnerability is ${currentVulnerability}`) + core.exportVariable('v', currentVulnerability); + + let issue = null + if (currentVulnerability != null) { + const trivyIssues = await get_trivy_issues(github.context.repo, token) + issue = trivyIssues.find(issue => issue.body.includes(currentVulnerability[0])) + } + + if (issue != null) { + core.info("Found existing issue. Skip creating a new one.") + } else { + issue = await createIssue(token, options) + } + const result: IssueResponse = { issueNumber: issue.number, htmlUrl: issue.html_url, }; + return result; } From ad34351a3f5c6d6be062048c6af0bcade633289f Mon Sep 17 00:00:00 2001 From: Tobias Wochinger Date: Tue, 28 Apr 2020 10:50:05 +0200 Subject: [PATCH 2/2] add option to fail if vulnerability was found --- README.md | 1 + action.yml | 4 ++++ dist/index.js | 3 +++ src/index.ts | 4 ++++ 4 files changed, 12 insertions(+) diff --git a/README.md b/README.md index 6bb2647..e082ff0 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ If vulnerabilities are found by Trivy, it creates the following GitHub Issue. |issue_title|False|Security Alert|Issue title| |issue_label|False|trivy,vulnerability|Issue label (separated by commma)| |issue_assignee|False|N/A|Issue assignee (separated by commma)| +|fail_on_vulnerabilities|False|false|Whether the action should fail if any vulnerabilities were found.| ### Outputs diff --git a/action.yml b/action.yml index a702767..50904bc 100644 --- a/action.yml +++ b/action.yml @@ -39,6 +39,10 @@ inputs: issue_assignee: description: 'Issue assignee (separated by commma)' required: false + fail_on_vulnerabilities: + description: Whether the action should fail if a vulnerability was found + default: 'false' + required: false outputs: issue_number: diff --git a/dist/index.js b/dist/index.js index 329287c..bb16b23 100644 --- a/dist/index.js +++ b/dist/index.js @@ -6593,6 +6593,9 @@ function run() { const output = yield issue_1.createOrUpdateIssue(token, image, issueOption); core.setOutput('html_url', output.htmlUrl); core.setOutput('issue_number', output.issueNumber.toString()); + if (core.getInput("fail_on_vulnerabilities") === 'true') { + core.setFailed(`Vulnerabilities found.\n${issueContent}`); + } } catch (error) { core.error(error.stack); diff --git a/src/index.ts b/src/index.ts index 9ebd9ff..c8cfcd4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -72,6 +72,10 @@ async function run() { const output: IssueResponse = await createOrUpdateIssue(token, image, issueOption); core.setOutput('html_url', output.htmlUrl); core.setOutput('issue_number', output.issueNumber.toString()); + + if (core.getInput("fail_on_vulnerabilities") === 'true') { + core.setFailed(`Vulnerabilities found.\n${issueContent}`) + } } catch (error) { core.error(error.stack); core.setFailed(error.message);