make KICS Github Action use KICS Docker Image (#32)
Signed-off-by: João Reigota <joao.reigota@checkmarx.com>
This commit is contained in:
@ -1,93 +0,0 @@
|
||||
const https = require('https')
|
||||
const filepath = require('path');
|
||||
const tc = require('@actions/tool-cache');
|
||||
const core = require("@actions/core");
|
||||
const os = require('os');
|
||||
|
||||
function getVersion(version) {
|
||||
let path = ''
|
||||
if (version == "latest") {
|
||||
path = '/repos/checkmarx/kics/releases/latest'
|
||||
} else {
|
||||
path = '/repos/checkmarx/kics/releases/tags/' + version
|
||||
}
|
||||
const options = {
|
||||
hostname: 'api.github.com',
|
||||
port: 443,
|
||||
path: path,
|
||||
headers: {
|
||||
'User-Agent': 'node.js'
|
||||
},
|
||||
method: 'GET'
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = https.get(options, (resp) => {
|
||||
console.log(`${options.method} https://${options.hostname}${options.path} ${resp.statusCode}`)
|
||||
let rawData = '';
|
||||
resp.on('data', (d) => {
|
||||
rawData += d;
|
||||
});
|
||||
resp.on('end', () => {
|
||||
try {
|
||||
const parsedData = JSON.parse(rawData);
|
||||
resolve(parsedData);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
req.on('error', (error) => {
|
||||
reject(error);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function getReleaseInfo(release) {
|
||||
const assets = release.assets || [];
|
||||
const os = process.platform;
|
||||
const arch = process.arch;
|
||||
let targetAsset;
|
||||
switch (os) {
|
||||
case 'darwin':
|
||||
targetAsset = assets.filter((asset) => asset.name.indexOf('darwin') !== -1 && asset.name.indexOf(arch) !== -1)[0];
|
||||
break;
|
||||
case 'linux':
|
||||
targetAsset = assets.filter((asset) => asset.name.indexOf('linux') !== -1 && asset.name.indexOf(arch) !== -1)[0];
|
||||
break;
|
||||
case 'win32':
|
||||
targetAsset = assets.filter((asset) => asset.name.indexOf('windows') !== -1 && asset.name.indexOf(arch) !== -1)[0];
|
||||
break;
|
||||
default:
|
||||
targetAsset = { size: 0, browser_download_url: '' };
|
||||
}
|
||||
return {
|
||||
binary: 'kics',
|
||||
size: targetAsset.size,
|
||||
browser_download_url: targetAsset.browser_download_url,
|
||||
version: release.tag_name,
|
||||
arch: arch
|
||||
};
|
||||
}
|
||||
|
||||
async function installKICS(kicsVersion) {
|
||||
let release = {};
|
||||
if (!kicsVersion || kicsVersion == "latest") {
|
||||
release = await getVersion("latest");
|
||||
} else {
|
||||
release = await getVersion(kicsVersion);
|
||||
}
|
||||
const releaseInfo = getReleaseInfo(release)
|
||||
let kicsPath = tc.find(releaseInfo.binary, releaseInfo.version, releaseInfo.arch);
|
||||
if (!kicsPath) {
|
||||
core.info(`Downloading ${releaseInfo.binary} ${releaseInfo.version} ${releaseInfo.arch}`);
|
||||
const kicsDownloadPath = await tc.downloadTool(releaseInfo.browser_download_url);
|
||||
const kicsExtractedFolder = await tc.extractTar(kicsDownloadPath, filepath.join(os.homedir(), 'kics', releaseInfo.version));
|
||||
kicsPath = await tc.cacheDir(kicsExtractedFolder, 'kics', releaseInfo.version, releaseInfo.arch);
|
||||
}
|
||||
core.addPath(kicsPath);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
installKICS
|
||||
}
|
102
src/main.js
102
src/main.js
@ -1,80 +1,58 @@
|
||||
const install = require("./install");
|
||||
const commenter = require("./commenter");
|
||||
const scanner = require("./scanner");
|
||||
const annotator = require("./annotator");
|
||||
|
||||
const core = require("@actions/core");
|
||||
const github = require("@actions/github");
|
||||
const io = require("@actions/io");
|
||||
|
||||
const filepath = require('path');
|
||||
const fs = require("fs");
|
||||
|
||||
const exitStatus = {
|
||||
results: {
|
||||
codes: {
|
||||
HIGH: 50,
|
||||
MEDIUM: 40,
|
||||
LOW: 30,
|
||||
INFO: 20,
|
||||
},
|
||||
isResultExitStatus: function (exitCode) {
|
||||
for (const key in this.codes) {
|
||||
if (this.codes[key] === exitCode) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setWorkflowStatus(statusCode) {
|
||||
console.log(`KICS scan status code: ${statusCode}`);
|
||||
|
||||
if (statusCode === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ignoreOnExit = core.getInput('ignore_on_exit');
|
||||
|
||||
if (ignoreOnExit.toLowerCase() === 'all') {
|
||||
console.log(`ignore_on_exit=all :: Ignoring exit code ${statusCode}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ignoreOnExit.toLowerCase() === 'results') {
|
||||
if (exitStatus.results.isResultExitStatus(statusCode)) {
|
||||
console.log(`ignore_on_exit=results :: Ignoring exit code ${statusCode}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ignoreOnExit.toLowerCase() === 'errors') {
|
||||
if (!exitStatus.results.isResultExitStatus(statusCode)) {
|
||||
console.log(`ignore_on_exit=errors :: Ignoring exit code ${statusCode}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
core.setFailed(`KICS scan failed with exit code ${statusCode}`);
|
||||
}
|
||||
|
||||
function readJSON(filename) {
|
||||
const rawdata = fs.readFileSync(filename);
|
||||
const parsedJSON = JSON.parse(rawdata.toString());
|
||||
return parsedJSON;
|
||||
}
|
||||
|
||||
function cleanupOutput(resultsJSONFile) {
|
||||
const outputFormats = core.getInput('output_formats');
|
||||
if (!outputFormats.toLowerCase().includes('json') || core.getInput('output_path') === '') {
|
||||
function cleanupOutput(resultsJSONFile, outputFormats) {
|
||||
if (!outputFormats.toLowerCase().includes('json') || outputFormats === '') {
|
||||
io.rmRF(resultsJSONFile);
|
||||
}
|
||||
}
|
||||
|
||||
function processOutputPath(output) {
|
||||
if (output === '') {
|
||||
return {
|
||||
path: "./",
|
||||
resultsJSONFile: "./results.json"
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
path: output,
|
||||
resultsJSONFile: filepath.join(output, "/results.json")
|
||||
}
|
||||
}
|
||||
|
||||
function setWorkflowStatus(statusCode) {
|
||||
console.log(`KICS scan status code: ${statusCode}`);
|
||||
|
||||
if (statusCode === "0") {
|
||||
return;
|
||||
}
|
||||
|
||||
core.setFailed(`KICS scan failed with exit code ${statusCode}`);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log("Running KICS action...");
|
||||
|
||||
// Get ENV variables
|
||||
const githubToken = process.env.INPUT_TOKEN;
|
||||
const enableComments = process.env.INPUT_ENABLE_COMMENTS;
|
||||
const outputPath = processOutputPath(process.env.INPUT_OUTPUT_PATH);
|
||||
const outputFormats = process.env.INPUT_OUTPUT_FORMATS;
|
||||
const exitCode = process.env.KICS_EXIT_CODE
|
||||
|
||||
try {
|
||||
const githubToken = core.getInput("token");
|
||||
const octokit = github.getOctokit(githubToken);
|
||||
let context = {};
|
||||
let repo = '';
|
||||
@ -90,17 +68,15 @@ async function main() {
|
||||
}
|
||||
}
|
||||
|
||||
await install.installKICS();
|
||||
const scanResults = await scanner.scanWithKICS();
|
||||
const parsedResults = readJSON(scanResults.resultsJSONFile);
|
||||
if (core.getInput('enable_comments').toLocaleLowerCase() === "true") {
|
||||
const parsedResults = readJSON(outputPath.resultsJSONFile);
|
||||
if (enableComments.toLocaleLowerCase() === "true") {
|
||||
await commenter.postPRComment(parsedResults, repo, prNumber, octokit);
|
||||
}
|
||||
|
||||
annotator.annotateChangesWithResults(parsedResults);
|
||||
|
||||
cleanupOutput(scanResults.resultsJSONFile);
|
||||
setWorkflowStatus(scanResults.statusCode);
|
||||
setWorkflowStatus(exitCode);
|
||||
cleanupOutput(outputPath.resultsJSONFile, outputFormats);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
core.setFailed(e.message);
|
||||
|
101
src/scanner.js
101
src/scanner.js
@ -1,101 +0,0 @@
|
||||
const exec = require('@actions/exec');
|
||||
const core = require("@actions/core");
|
||||
const filepath = require('path');
|
||||
|
||||
const kicsBinary = 'kics';
|
||||
|
||||
const kicsInput = {
|
||||
path: { value_type: "list", flag: '--path', value: core.getInput('path') },
|
||||
ignore_on_exit: { value_type: "list", flag: '--ignore-on-exit', value: core.getInput('ignore_on_exit') },
|
||||
fail_on: { value_type: "list", flag: '--fail-on', value: core.getInput('fail_on') },
|
||||
timeout: { value_type: "int", flag: '--timeout', value: core.getInput('timeout') },
|
||||
profiling: { value_type: "list", flag: '--profiling', value: core.getInput('profiling') },
|
||||
config_path: { value_type: "string", flag: '--config', value: core.getInput('config_path') },
|
||||
payload_path: { value_type: "string", flag: '--payload-path', value: core.getInput('payload_path') },
|
||||
exclude_paths: { value_type: "list", flag: '--exclude-paths', value: core.getInput('exclude_paths') },
|
||||
exclude_queries: { value_type: "list", flag: '--exclude-queries', value: core.getInput('exclude_queries') },
|
||||
exclude_categories: { value_type: "list", flag: '--exclude-categories', value: core.getInput('exclude_categories') },
|
||||
exclude_results: { value_type: "list", flag: '--exclude-results', value: core.getInput('exclude_results') },
|
||||
output_formats: { value_type: "list", flag: '--report-formats', value: core.getInput('output_formats') },
|
||||
output_path: { value_type: "string", flag: '--output-path', value: core.getInput('output_path') },
|
||||
queries: { value_type: "string", flag: '--queries-path', value: core.getInput('queries') },
|
||||
verbose: { value_type: "bool", flag: '--verbose', value: core.getInput('verbose') },
|
||||
secrets_regexes_path: { value_type: "string", flag: '--secrets-regexes-path', value: core.getInput('secrets_regexes_path') },
|
||||
libraries_path: { value_type: "string", flag: '--libraries-path', value: core.getInput('libraries-path') },
|
||||
disable_secrets: { value_type: "bool", flag: '--disable-secrets', value: core.getInput('disable_secrets') },
|
||||
disable_full_descriptions: { value_type: "bool", flag: '--disable-full-descriptions', value: core.getInput('disable_full_descriptions') },
|
||||
types: { value_type: "list", flag: '--types', value: core.getInput('types') },
|
||||
bom: { value_type: "bool", flag: '--bom', value: core.getInput('bom') },
|
||||
};
|
||||
|
||||
function addJSONReportFormat(cmdArgs) {
|
||||
const outputFormats = core.getInput('output_formats');
|
||||
if (outputFormats.toLowerCase().indexOf('json') == -1) {
|
||||
cmdArgs.push('--report-formats');
|
||||
cmdArgs.push('json');
|
||||
}
|
||||
}
|
||||
|
||||
function addKICSCmdArgs(cmdArgs) {
|
||||
for (let input in kicsInput) {
|
||||
if (kicsInput[input].value_type === 'string') {
|
||||
if (kicsInput[input].value) {
|
||||
cmdArgs.push(kicsInput[input].flag);
|
||||
cmdArgs.push(kicsInput[input].value);
|
||||
}
|
||||
} else if (kicsInput[input].value_type === 'list') {
|
||||
if (kicsInput[input].value) {
|
||||
if (kicsInput[input].value.indexOf(',') > -1) {
|
||||
kicsInput[input].value.split(',').forEach(value => {
|
||||
cmdArgs.push(kicsInput[input].flag);
|
||||
cmdArgs.push(value);
|
||||
});
|
||||
} else {
|
||||
cmdArgs.push(kicsInput[input].flag);
|
||||
cmdArgs.push(kicsInput[input].value);
|
||||
}
|
||||
}
|
||||
} else if (kicsInput[input].value_type === 'bool') {
|
||||
if (kicsInput[input].value) {
|
||||
cmdArgs.push(kicsInput[input].flag);
|
||||
}
|
||||
} else if (kicsInput[input].value_type === 'int') {
|
||||
if (kicsInput[input].value) {
|
||||
cmdArgs.push(kicsInput[input].flag);
|
||||
cmdArgs.push(kicsInput[input].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function scanWithKICS() {
|
||||
let resultsJSONFile;
|
||||
|
||||
if (!kicsInput.path.value) {
|
||||
core.error('Path to scan is not set');
|
||||
core.setFailed('Path to scan is not set');
|
||||
}
|
||||
let cmdArgs = [];
|
||||
addKICSCmdArgs(cmdArgs);
|
||||
|
||||
// making sure results.json is always created
|
||||
if (!cmdArgs.find(arg => arg == '--output-path')) {
|
||||
cmdArgs.push('--output-path');
|
||||
cmdArgs.push('./');
|
||||
resultsJSONFile = './results.json';
|
||||
} else {
|
||||
let resultsDir = core.getInput('output_path');
|
||||
resultsJSONFile = filepath.join(resultsDir, '/results.json');
|
||||
}
|
||||
addJSONReportFormat(cmdArgs);
|
||||
|
||||
exitCode = await exec.exec(`${kicsBinary} scan --no-progress ${cmdArgs.join(" ")}`, [], { ignoreReturnCode: true });
|
||||
return {
|
||||
statusCode: exitCode,
|
||||
resultsJSONFile: resultsJSONFile
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
scanWithKICS
|
||||
};
|
Reference in New Issue
Block a user