From e28e1625fdca491d5b678b8c48c39093b206c224 Mon Sep 17 00:00:00 2001 From: rasta-rocket Date: Fri, 17 Apr 2026 13:50:22 +0200 Subject: [PATCH 1/2] feat: add output_name input to map KICS --output-name CLI option --- action.yml | 5 +++++ entrypoint.sh | 10 +++++++--- src/main.js | 9 +++++---- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/action.yml b/action.yml index 58b0223..cba9b45 100644 --- a/action.yml +++ b/action.yml @@ -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 @@ -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 }} @@ -136,6 +140,7 @@ runs: - ${{ inputs.exclude_gitignore}} - ${{ inputs.output_formats }} - ${{ inputs.output_path }} + - ${{ inputs.output_name }} - ${{ inputs.payload_path }} - ${{ inputs.queries }} - ${{ inputs.verbose }} diff --git a/entrypoint.sh b/entrypoint.sh index 7f606bd..d02481c 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -35,6 +35,7 @@ fi [[ ! -z "$INPUT_SECRETS_REGEXES_PATH" ]] && SECRETS_REGEXES_PATH_PARAM="-r $INPUT_SECRETS_REGEXES_PATH" [[ ! -z "$INPUT_IGNORE_ON_EXIT" ]] && IGNORE_ON_EXIT_PARAM="--ignore-on-exit $INPUT_IGNORE_ON_EXIT" [[ ! -z "$INPUT_CLOUD_PROVIDER" ]] && CLOUD_PROVIDER="--cloud-provider $INPUT_CLOUD_PROVIDER" +[[ ! -z "$INPUT_OUTPUT_NAME" ]] && OUTPUT_NAME_PARAM="--output-name $INPUT_OUTPUT_NAME" [[ ! -z "$INPUT_VERBOSE" ]] && VERBOSE_PARAM="-v" @@ -64,7 +65,10 @@ fi # Check for Output Path # ############################ -CP_PATH="./results.json" +RESULTS_FILENAME="results" +[[ ! -z "$INPUT_OUTPUT_NAME" ]] && RESULTS_FILENAME="$INPUT_OUTPUT_NAME" + +CP_PATH="./${RESULTS_FILENAME}.json" if [ ! -z "$INPUT_OUTPUT_PATH" ]; then OUTPUT_PATH_PARAM="-o $INPUT_OUTPUT_PATH" CP_PATH=$INPUT_OUTPUT_PATH @@ -77,8 +81,8 @@ fi #################### cd $GITHUB_WORKSPACE echo "${DATETIME} - INF : about to scan directory $INPUT_PATH" -echo "${DATETIME} - INF : kics command kics $INPUT_PARAM $OUTPUT_PATH_PARAM $OUTPUT_FORMATS_PARAM $PLATFORM_TYPE_PARAM $PAYLOAD_PATH_PARAM $CONFIG_PATH_PARAM $EXCLUDE_PATHS_PARAM $EXCLUDE_CATEGORIES_PARAM $EXCLUDE_RESULTS_PARAM $EXCLUDE_SEVERITIES_PARAM $EXCLUDE_QUERIES_PARAM $EXCLUDE_GITIGNORE $QUERIES_PARAM $VERBOSE_PARAM $IGNORE_ON_EXIT_PARAM $FAIL_ON_PARAM $TIMEOUT_PARAM $PROFILING_PARAM $BOM_PARAM $INCLUDE_QUERIES_PARAM $DISABLE_SECRETS_PARAM $DISABLE_FULL_DESCRIPTIONS_PARAM $LIBRARIES_PATH_PARAM $SECRETS_REGEXES_PATH_PARAM $CLOUD_PROVIDER" -/app/bin/kics scan --no-progress $INPUT_PARAM $OUTPUT_PATH_PARAM $OUTPUT_FORMATS_PARAM $PLATFORM_TYPE_PARAM $PAYLOAD_PATH_PARAM $CONFIG_PATH_PARAM $EXCLUDE_PATHS_PARAM $EXCLUDE_CATEGORIES_PARAM $EXCLUDE_RESULTS_PARAM $EXCLUDE_SEVERITIES_PARAM $EXCLUDE_QUERIES_PARAM $EXCLUDE_GITIGNORE $QUERIES_PARAM $VERBOSE_PARAM $IGNORE_ON_EXIT_PARAM $FAIL_ON_PARAM $TIMEOUT_PARAM $PROFILING_PARAM $BOM_PARAM $INCLUDE_QUERIES_PARAM $DISABLE_SECRETS_PARAM $DISABLE_FULL_DESCRIPTIONS_PARAM $LIBRARIES_PATH_PARAM $SECRETS_REGEXES_PATH_PARAM $CLOUD_PROVIDER +echo "${DATETIME} - INF : kics command kics $INPUT_PARAM $OUTPUT_PATH_PARAM $OUTPUT_NAME_PARAM $OUTPUT_FORMATS_PARAM $PLATFORM_TYPE_PARAM $PAYLOAD_PATH_PARAM $CONFIG_PATH_PARAM $EXCLUDE_PATHS_PARAM $EXCLUDE_CATEGORIES_PARAM $EXCLUDE_RESULTS_PARAM $EXCLUDE_SEVERITIES_PARAM $EXCLUDE_QUERIES_PARAM $EXCLUDE_GITIGNORE $QUERIES_PARAM $VERBOSE_PARAM $IGNORE_ON_EXIT_PARAM $FAIL_ON_PARAM $TIMEOUT_PARAM $PROFILING_PARAM $BOM_PARAM $INCLUDE_QUERIES_PARAM $DISABLE_SECRETS_PARAM $DISABLE_FULL_DESCRIPTIONS_PARAM $LIBRARIES_PATH_PARAM $SECRETS_REGEXES_PATH_PARAM $CLOUD_PROVIDER" +/app/bin/kics scan --no-progress $INPUT_PARAM $OUTPUT_PATH_PARAM $OUTPUT_NAME_PARAM $OUTPUT_FORMATS_PARAM $PLATFORM_TYPE_PARAM $PAYLOAD_PATH_PARAM $CONFIG_PATH_PARAM $EXCLUDE_PATHS_PARAM $EXCLUDE_CATEGORIES_PARAM $EXCLUDE_RESULTS_PARAM $EXCLUDE_SEVERITIES_PARAM $EXCLUDE_QUERIES_PARAM $EXCLUDE_GITIGNORE $QUERIES_PARAM $VERBOSE_PARAM $IGNORE_ON_EXIT_PARAM $FAIL_ON_PARAM $TIMEOUT_PARAM $PROFILING_PARAM $BOM_PARAM $INCLUDE_QUERIES_PARAM $DISABLE_SECRETS_PARAM $DISABLE_FULL_DESCRIPTIONS_PARAM $LIBRARIES_PATH_PARAM $SECRETS_REGEXES_PATH_PARAM $CLOUD_PROVIDER export KICS_EXIT_CODE=$? diff --git a/src/main.js b/src/main.js index ef5fb35..a3c427c 100644 --- a/src/main.js +++ b/src/main.js @@ -18,17 +18,18 @@ 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`) } } @@ -52,7 +53,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 From ad02c30d95e024bfca69e3e420eeafabac6ac8dc Mon Sep 17 00:00:00 2001 From: Artur Ribeiro <153724638+cx-artur-ribeiro@users.noreply.github.com> Date: Fri, 16 Oct 2026 14:40:24 +0100 Subject: [PATCH 2/2] feat: pass output_name safely, document it and cover it with tests - Pass --output-name as a single argument so a name with spaces is not split. - Drop a trailing .json from the name, KICS appends the extension itself. - Resolve the entrypoint.sh conflict with the path flags now kept in "$@". - Remove the output_name entry from args, nothing reads positional arguments. - Document output_name in the README. - Cover the flag, the report lookup and the cleanup with tests. --- README.md | 1 + action.yml | 1 - entrypoint.sh | 6 +++++- test/e2e/entrypoint.test.js | 28 ++++++++++++++++++++++++++++ test/helpers/run-entrypoint.js | 7 ++++++- 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 132fef5..53d10d6 100644 --- a/README.md +++ b/README.md @@ -193,6 +193,7 @@ Ensure that you're using the { ['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'], @@ -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) => { @@ -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'], @@ -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 diff --git a/test/helpers/run-entrypoint.js b/test/helpers/run-entrypoint.js index 27550cb..1d45270 100644 --- a/test/helpers/run-entrypoint.js +++ b/test/helpers/run-entrypoint.js @@ -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