Skip to content

Commit ecdaa80

Browse files
authored
Allow input parameter output-format and output report to be used (#187)
1 parent 7ff5325 commit ecdaa80

File tree

5 files changed

+75
-4
lines changed

5 files changed

+75
-4
lines changed

action.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ inputs:
1717
description: "Set to false to avoid failing based on severity-cutoff. Default is to fail when severity-cutoff is reached (or surpassed)"
1818
required: false
1919
default: "true"
20+
output-format:
21+
description: 'Set the output parameter after successful action execution. Valid choices are "json" and "sarif".'
22+
required: false
23+
default: "sarif"
2024
acs-report-enable:
2125
description: "Generate a SARIF report and set the `sarif` output parameter after successful action execution. This report is compatible with GitHub Automated Code Scanning (ACS), as the artifact to upload for display as a Code Scanning Alert report."
2226
required: false
@@ -28,6 +32,8 @@ inputs:
2832
outputs:
2933
sarif:
3034
description: "Path to a SARIF report file for the image"
35+
report:
36+
description: "Path to a JSON report file for the image"
3137
runs:
3238
using: "node16"
3339
main: "dist/index.js"

dist/index.js

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,14 @@ async function run() {
103103
const source = sourceInput();
104104
const failBuild = core.getInput("fail-build") || "true";
105105
const acsReportEnable = core.getInput("acs-report-enable") || "true";
106+
const outputFormat = core.getInput("output-format") || "sarif";
106107
const severityCutoff = core.getInput("severity-cutoff") || "medium";
107108
const out = await runScan({
108109
source,
109110
failBuild,
110111
acsReportEnable,
111112
severityCutoff,
113+
outputFormat,
112114
});
113115
Object.keys(out).map((key) => {
114116
core.setOutput(key, out[key]);
@@ -118,7 +120,13 @@ async function run() {
118120
}
119121
}
120122

121-
async function runScan({ source, failBuild, acsReportEnable, severityCutoff }) {
123+
async function runScan({
124+
source,
125+
failBuild,
126+
acsReportEnable,
127+
severityCutoff,
128+
outputFormat,
129+
}) {
122130
const out = {};
123131

124132
const env = {
@@ -139,6 +147,7 @@ async function runScan({ source, failBuild, acsReportEnable, severityCutoff }) {
139147
}
140148

141149
const SEVERITY_LIST = ["negligible", "low", "medium", "high", "critical"];
150+
const FORMAT_LIST = ["sarif", "json"];
142151
let cmdArgs = [];
143152

144153
if (core.isDebug()) {
@@ -149,10 +158,16 @@ async function runScan({ source, failBuild, acsReportEnable, severityCutoff }) {
149158

150159
acsReportEnable = acsReportEnable.toLowerCase() === "true";
151160

161+
if (outputFormat !== "sarif" && acsReportEnable) {
162+
throw new Error(
163+
`Invalid output-format selected. If acs-report-enabled is true (which is the default if it is omitted), the output-format parameter must be sarif or must be omitted`
164+
);
165+
}
166+
152167
if (acsReportEnable) {
153168
cmdArgs.push("-o", "sarif");
154169
} else {
155-
cmdArgs.push("-o", "json");
170+
cmdArgs.push("-o", outputFormat);
156171
}
157172

158173
if (
@@ -166,6 +181,17 @@ async function runScan({ source, failBuild, acsReportEnable, severityCutoff }) {
166181
`Invalid severity-cutoff value is set to ${severityCutoff} - please ensure you are choosing either negligible, low, medium, high, or critical`
167182
);
168183
}
184+
if (
185+
!FORMAT_LIST.some(
186+
(item) =>
187+
typeof outputFormat.toLowerCase() === "string" &&
188+
item === outputFormat.toLowerCase()
189+
)
190+
) {
191+
throw new Error(
192+
`Invalid output-format value is set to ${outputFormat} - please ensure you are choosing either json or sarif`
193+
);
194+
}
169195

170196
core.debug(`Installing grype version ${grypeVersion}`);
171197
await installGrype(grypeVersion);
@@ -174,6 +200,7 @@ async function runScan({ source, failBuild, acsReportEnable, severityCutoff }) {
174200
core.debug("Fail Build: " + failBuild);
175201
core.debug("Severity Cutoff: " + severityCutoff);
176202
core.debug("ACS Enable: " + acsReportEnable);
203+
core.debug("Output Format: " + outputFormat);
177204

178205
core.debug("Creating options for GRYPE analyzer");
179206

@@ -225,6 +252,10 @@ async function runScan({ source, failBuild, acsReportEnable, severityCutoff }) {
225252
const SARIF_FILE = "./results.sarif";
226253
fs.writeFileSync(SARIF_FILE, cmdOutput);
227254
out.sarif = SARIF_FILE;
255+
} else {
256+
const REPORT_FILE = "./results.report";
257+
fs.writeFileSync(REPORT_FILE, cmdOutput);
258+
out.report = REPORT_FILE;
228259
}
229260

230261
if (failBuild === true && exitCode > 0) {

index.js

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,14 @@ async function run() {
8888
const source = sourceInput();
8989
const failBuild = core.getInput("fail-build") || "true";
9090
const acsReportEnable = core.getInput("acs-report-enable") || "true";
91+
const outputFormat = core.getInput("output-format") || "sarif";
9192
const severityCutoff = core.getInput("severity-cutoff") || "medium";
9293
const out = await runScan({
9394
source,
9495
failBuild,
9596
acsReportEnable,
9697
severityCutoff,
98+
outputFormat,
9799
});
98100
Object.keys(out).map((key) => {
99101
core.setOutput(key, out[key]);
@@ -103,7 +105,13 @@ async function run() {
103105
}
104106
}
105107

106-
async function runScan({ source, failBuild, acsReportEnable, severityCutoff }) {
108+
async function runScan({
109+
source,
110+
failBuild,
111+
acsReportEnable,
112+
severityCutoff,
113+
outputFormat,
114+
}) {
107115
const out = {};
108116

109117
const env = {
@@ -124,6 +132,7 @@ async function runScan({ source, failBuild, acsReportEnable, severityCutoff }) {
124132
}
125133

126134
const SEVERITY_LIST = ["negligible", "low", "medium", "high", "critical"];
135+
const FORMAT_LIST = ["sarif", "json"];
127136
let cmdArgs = [];
128137

129138
if (core.isDebug()) {
@@ -134,10 +143,16 @@ async function runScan({ source, failBuild, acsReportEnable, severityCutoff }) {
134143

135144
acsReportEnable = acsReportEnable.toLowerCase() === "true";
136145

146+
if (outputFormat !== "sarif" && acsReportEnable) {
147+
throw new Error(
148+
`Invalid output-format selected. If acs-report-enabled is true (which is the default if it is omitted), the output-format parameter must be sarif or must be omitted`
149+
);
150+
}
151+
137152
if (acsReportEnable) {
138153
cmdArgs.push("-o", "sarif");
139154
} else {
140-
cmdArgs.push("-o", "json");
155+
cmdArgs.push("-o", outputFormat);
141156
}
142157

143158
if (
@@ -151,6 +166,17 @@ async function runScan({ source, failBuild, acsReportEnable, severityCutoff }) {
151166
`Invalid severity-cutoff value is set to ${severityCutoff} - please ensure you are choosing either negligible, low, medium, high, or critical`
152167
);
153168
}
169+
if (
170+
!FORMAT_LIST.some(
171+
(item) =>
172+
typeof outputFormat.toLowerCase() === "string" &&
173+
item === outputFormat.toLowerCase()
174+
)
175+
) {
176+
throw new Error(
177+
`Invalid output-format value is set to ${outputFormat} - please ensure you are choosing either json or sarif`
178+
);
179+
}
154180

155181
core.debug(`Installing grype version ${grypeVersion}`);
156182
await installGrype(grypeVersion);
@@ -159,6 +185,7 @@ async function runScan({ source, failBuild, acsReportEnable, severityCutoff }) {
159185
core.debug("Fail Build: " + failBuild);
160186
core.debug("Severity Cutoff: " + severityCutoff);
161187
core.debug("ACS Enable: " + acsReportEnable);
188+
core.debug("Output Format: " + outputFormat);
162189

163190
core.debug("Creating options for GRYPE analyzer");
164191

@@ -210,6 +237,10 @@ async function runScan({ source, failBuild, acsReportEnable, severityCutoff }) {
210237
const SARIF_FILE = "./results.sarif";
211238
fs.writeFileSync(SARIF_FILE, cmdOutput);
212239
out.sarif = SARIF_FILE;
240+
} else {
241+
const REPORT_FILE = "./results.report";
242+
fs.writeFileSync(REPORT_FILE, cmdOutput);
243+
out.report = REPORT_FILE;
213244
}
214245

215246
if (failBuild === true && exitCode > 0) {

tests/grype_command.test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ describe("Grype command", () => {
2929
debug: "false",
3030
failBuild: "false",
3131
acsReportEnable: "true",
32+
outputFormat: "sarif",
3233
severityCutoff: "high",
3334
version: "0.6.0",
3435
});
@@ -40,6 +41,7 @@ describe("Grype command", () => {
4041
source: "asdf",
4142
failBuild: "false",
4243
acsReportEnable: "false",
44+
outputFormat: "json",
4345
severityCutoff: "low",
4446
version: "0.6.0",
4547
});

tests/sarif_output.test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const testSource = async (source, vulnerabilities) => {
1818
debug: "false",
1919
failBuild: "false",
2020
acsReportEnable: "true",
21+
outputFormat: "sarif",
2122
severityCutoff: "medium",
2223
});
2324

0 commit comments

Comments
 (0)