Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ Ensure that you're using the <a href="https://github.com/Checkmarx/kics-github-a
| include_queries | a227ec01-f97a-4084-91a4-47b350c1db54 | include only specified list of queries to the scan, cannot be provided with query exclusion flags | String | No | N/A |
| output_formats | 'json,sarif' | formats in which the results report will be exported | String | No | json |
| output_path | myResults/ | file path to store result in json format | String | No | "./" |
| output_name | my-results | name of the results report files, without extension (KICS adds .json, .sarif); defaults to results | String | No | results |
| payload_path | /tmp/mypayload.json | file path to store source internal representation in JSON format | String | No | N/A |
| queries | | path to directory with queries (default "./assets/queries") | String | No | ./assets/queries downloaded with the binaries |
| verbose | true | verbose scan | Boolean | No | false |
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ inputs:
output_path:
description: "directory to store results report"
required: false
output_name:
description: "name for output results file"
required: false
payload_path:
description: "file path to store source internal representation in JSON format"
required: false
Expand Down Expand Up @@ -113,6 +116,7 @@ runs:
env:
INPUT_TOKEN: ${{ inputs.token }}
INPUT_OUTPUT_PATH: ${{ inputs.output_path }}
INPUT_OUTPUT_NAME: ${{ inputs.output_name }}
INPUT_ENABLE_ANNOTATIONS: ${{ inputs.enable_annotations }}
INPUT_ENABLE_COMMENTS: ${{ inputs.enable_comments }}
INPUT_ENABLE_JOBS_SUMMARY: ${{ inputs.enable_jobs_summary }}
Expand Down
6 changes: 5 additions & 1 deletion entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ fi
# Check for Output Path #
############################

CP_PATH="./results.json"
# KICS appends the extension itself, so a trailing .json would only confuse the file lookup
INPUT_OUTPUT_NAME="${INPUT_OUTPUT_NAME%.json}"
[[ ! -z "$INPUT_OUTPUT_NAME" ]] && set -- "$@" --output-name "$INPUT_OUTPUT_NAME"

CP_PATH="./${INPUT_OUTPUT_NAME:-results}.json"
if [ ! -z "$INPUT_OUTPUT_PATH" ]; then
set -- "$@" -o "$INPUT_OUTPUT_PATH"
CP_PATH=$INPUT_OUTPUT_PATH
Expand Down
9 changes: 5 additions & 4 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,18 @@ async function cleanupOutput(resultsJSONFile, outputFormats) {
}
}

function processOutputPath(output) {
function processOutputPath(output, outputName) {
const resultsFilename = outputName || "results";
if (output === '') {
return {
path: "./",
resultsJSONFile: "./results.json"
resultsJSONFile: `./${resultsFilename}.json`
}
}

return {
path: output,
resultsJSONFile: filepath.join(output, "/results.json")
resultsJSONFile: filepath.join(output, `/${resultsFilename}.json`)
}
}

Expand All @@ -56,7 +57,7 @@ async function main() {
let enableJobsSummary = process.env.INPUT_ENABLE_JOBS_SUMMARY;
const commentsWithQueries = process.env.INPUT_COMMENTS_WITH_QUERIES;
const excludedColumnsForCommentsWithQueries = process.env.INPUT_EXCLUDED_COLUMNS_FOR_COMMENTS_WITH_QUERIES.split(',');
const outputPath = processOutputPath(process.env.INPUT_OUTPUT_PATH);
const outputPath = processOutputPath(process.env.INPUT_OUTPUT_PATH, process.env.INPUT_OUTPUT_NAME);
const outputFormats = process.env.INPUT_OUTPUT_FORMATS;
const exitCode = process.env.KICS_EXIT_CODE

Expand Down
28 changes: 28 additions & 0 deletions test/e2e/entrypoint.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ test('inputs mapped to KICS flags', async (t) => {
['exclude_categories', 'Observability,Backup', '--exclude-categories'],
['platform_type', 'Terraform,Dockerfile', '--type'],
['type', 'Ansible,Dockerfile', '--type'],
['output_name', 'my-results', '--output-name'],
['fail_on', 'high,medium', '--fail-on'],
['timeout', '60', '--timeout'],
['profiling', 'CPU', '--profiling'],
Expand Down Expand Up @@ -93,6 +94,7 @@ test('inputs mapped to KICS flags', async (t) => {
['secrets_regexes_path', 'my dir/secret regexes.json', '-r'],
['queries', 'my queries,team queries', '-q'],
['output_path', 'my out', '-o'],
['output_name', 'my results', '--output-name'],
]
for (const [input, value, flag] of withSpaces) {
await t.test(`${input} keeps a value containing spaces as one argument`, async (t) => {
Expand All @@ -101,6 +103,15 @@ test('inputs mapped to KICS flags', async (t) => {
})
}

await t.test('output_name is given to KICS without the .json extension it appends itself', async (t) => {
const run = await runEntrypoint(t, { inputs: { output_name: 'my-results.json' } })
assert.equal(flagValue(run.args, '--output-name'), 'my-results')
})

await t.test('output_name left unset -> no --output-name', async (t) => {
assert.ok(!(await runEntrypoint(t)).args.includes('--output-name'))
})

const switches = [
['exclude_gitignore', '--exclude-gitignore'],
['disable_secrets', '--disable-secrets'],
Expand Down Expand Up @@ -248,6 +259,23 @@ test('whole action: entrypoint, KICS, JavaScript stage and GitHub', async (t) =>
assert.match(run.summary, /\| TOTAL \| 4 \|/, run.stdout + run.stderr)
})

for (const name of ['my-results', 'my results', 'my-results.json']) {
await t.test(`reports named "${name}" through output_name are picked up`, async (t) => {
const run = await runEntrypoint(t, { runMain: true, results: kicsResults(), inputs: { output_name: name, enable_jobs_summary: 'true' } })
assert.match(run.summary, /\| TOTAL \| 4 \|/, run.stdout + run.stderr)
})
}

await t.test('reports named through output_name are picked up from output_path', async (t) => {
const run = await runEntrypoint(t, { runMain: true, results: kicsResults(), inputs: { output_name: 'my-results', output_path: 'reports', enable_jobs_summary: 'true' } })
assert.match(run.summary, /\| TOTAL \| 4 \|/, run.stdout + run.stderr)
})

await t.test('the workspace is left without the named report nobody asked for', async (t) => {
const run = await runEntrypoint(t, { runMain: true, results: kicsResults(), inputs: { output_name: 'my-results', output_formats: 'sarif' } })
assert.equal(fs.existsSync(path.join(run.workspace, 'my-results.json')), false)
})

await t.test('results.json is left readable for the next workflow steps', async (t) => {
const run = await runEntrypoint(t, { results: kicsResults() })
const mode = fs.statSync(path.join(run.workspace, 'results.json')).mode
Expand Down
7 changes: 6 additions & 1 deletion test/helpers/run-entrypoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,18 @@ function sandboxedEntrypoint(sandbox) {
const FAKE_KICS = `#!/bin/bash
printf '%s\\n' "$@" > "$SANDBOX/kics-args.txt"
out=./
name=""
while [ $# -gt 0 ]; do
if [ "$1" = "-o" ]; then out="$2"; fi
if [ "$1" = "--output-name" ]; then name="$2"; fi
shift
done
# like KICS: the name comes from --output-name (or the config file), and a trailing .json is not doubled
name="\${name:-\${FAKE_KICS_NAME:-results}}"
name="\${name%.json}"
if [ -n "$FAKE_KICS_RESULTS" ]; then
mkdir -p "$out"
file="$out/\${FAKE_KICS_NAME:-results}.json"
file="$out/$name.json"
cp "$FAKE_KICS_RESULTS" "$file"
chmod 755 "$file" # KICS v2.1.20 writes its reports world-readable
fi
Expand Down
Loading