From 940bb1b41494d9f30ace1834ed302e0242ea0ec1 Mon Sep 17 00:00:00 2001 From: Jeremy Dubreil Date: Fri, 5 Jun 2026 14:07:49 +0000 Subject: [PATCH] chore(COD-7026): split the and command into two functions --- src/index.ts | 30 ++----- src/util.ts | 249 ++++++++++++++++++++++++--------------------------- 2 files changed, 122 insertions(+), 157 deletions(-) diff --git a/src/index.ts b/src/index.ts index 3fa9be0e..d111d741 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,10 +10,10 @@ import { } from './actions' import { callCommand, - runCodesec, + runCodesecScan, + runCodesecCompare, getModifiedFiles, getOptionalEnvVariable, - readMarkdownFile, shouldRunIaCScanner, } from './util' import { simpleGit } from 'simple-git' @@ -79,8 +79,7 @@ async function runAnalysis() { } if (!cacheHit) { - let success = await runCodesec( - 'scan', + let success = await runCodesecScan( enableIacRunning, enableScaRunning, resultsPath, @@ -185,30 +184,11 @@ async function displayResults() { } // Run codesec compare mode with available scanners - const resultsPath = path.join(process.cwd(), 'scan-results') - await runCodesec( - 'compare', + const message = await runCodesecCompare( enableIacRunning && iacAvailable, - enableScaRunning && scaAvailable, - resultsPath + enableScaRunning && scaAvailable ) - // Read comparison output - check all possible outputs - const outputs = [ - 'scan-results/compare/merged-compare.md', - 'scan-results/compare/sca-compare.md', - 'scan-results/compare/iac-compare.md', - ] - - let message: string | null = null - for (const output of outputs) { - if (existsSync(output)) { - info(`Using comparison output: ${output}`) - message = readMarkdownFile(output) - break - } - } - if (!message) { info('No comparison output produced. No changes detected.') setOutput('display-completed', true) diff --git a/src/util.ts b/src/util.ts index 4e0ba95c..99d5fe24 100644 --- a/src/util.ts +++ b/src/util.ts @@ -157,18 +157,7 @@ export function shouldRunIaCScanner(modifiedFiles: string): boolean { }) } -// runCodesec - Docker-based scanner using codesec:latest image -// -// Modes: -// 1. action='scan', scanTarget='new'/'old' -> produces analysis for PR comment -// 2. action='scan', scanTarget='scan' -> full scan for scheduled events (uploads to Lacework) -// 3. action='compare' -> compares new/old results, generates diff markdown for PR comment -// -// Parameters: -// - runIac/runSca: which scanners to enable (default false - enable when ready to test) -// - scanTarget: 'new', 'old', or 'scan' depending on mode -export async function runCodesec( - action: string, +export async function runCodesecScan( runIac: boolean = false, runSca: boolean = false, reportsDir: string, @@ -179,137 +168,133 @@ export async function runCodesec( const lwApiKey = getRequiredEnvVariable('LW_API_KEY') const lwApiSecret = getRequiredEnvVariable('LW_API_SECRET') - if (action === 'scan') { - const containerName = `codesec-scan-${scanTarget || 'default'}` - - info(`Running codesec scan (target: ${scanTarget || 'scan'})`) - - // Create env file with GitHub CI vars for the lacework iac binary - const envFile = createEnvFile() - - // Run the scanner - const dockerArgs = [ - 'run', - '--name', - containerName, - '-v', - `${process.cwd()}:/app/src`, - '--env-file', - envFile, - '-e', - `WORKSPACE=src`, - '-e', - `LW_ACCOUNT=${lwAccount}`, - '-e', - `LW_API_KEY=${lwApiKey}`, - '-e', - `LW_API_SECRET=${lwApiSecret}`, - '-e', - `RUN_SCA=${runSca}`, - '-e', - `RUN_IAC=${runIac}`, - '-e', - `SCAN_TARGET=${scanTarget || 'scan'}`, - ...(modifiedFiles ? ['-e', `MODIFIED_FILES=${modifiedFiles}`] : []), - 'lacework/codesec:latest', - 'scan', - ] - - await callCommand('docker', ...dockerArgs) - - // Copy results out of container to temp dir - if (runSca) { - const scaDir = path.join(reportsDir, 'sca') - mkdirSync(scaDir, { recursive: true }) - await callCommand( - 'docker', - 'container', - 'cp', - `${containerName}:/tmp/scan-results/sca/sca-${scanTarget || 'scan'}.sarif`, - path.join(scaDir, `sca-${scanTarget || 'scan'}.sarif`) - ) - } + const containerName = `codesec-scan-${scanTarget || 'default'}` + + info(`Running codesec scan (target: ${scanTarget || 'scan'})`) + + const envFile = createEnvFile() + + const dockerArgs = [ + 'run', + '--name', + containerName, + '-v', + `${process.cwd()}:/app/src`, + '--env-file', + envFile, + '-e', + `WORKSPACE=src`, + '-e', + `LW_ACCOUNT=${lwAccount}`, + '-e', + `LW_API_KEY=${lwApiKey}`, + '-e', + `LW_API_SECRET=${lwApiSecret}`, + '-e', + `RUN_SCA=${runSca}`, + '-e', + `RUN_IAC=${runIac}`, + '-e', + `SCAN_TARGET=${scanTarget || 'scan'}`, + ...(modifiedFiles ? ['-e', `MODIFIED_FILES=${modifiedFiles}`] : []), + 'lacework/codesec:latest', + 'scan', + ] - if (runIac) { - const iacDir = path.join(reportsDir, 'iac') - mkdirSync(iacDir, { recursive: true }) - await callCommand( - 'docker', - 'container', - 'cp', - `${containerName}:/tmp/scan-results/iac/iac-${scanTarget || 'scan'}.json`, - path.join(iacDir, `iac-${scanTarget || 'scan'}.json`) - ) - } + await callCommand('docker', ...dockerArgs) - // Cleanup container - await callCommand('docker', 'rm', containerName) - } else if (action === 'compare') { - const containerName = 'codesec-compare' - - info('Running codesec compare') - - // Create env file with GitHub CI vars for the lacework iac binary - const envFile = createEnvFile() - - // Append LW_UI_LINK so the image can pass it to `lacework sca compare --ui-link` - const uiLink = generateUILink() - writeFileSync(envFile, `\nLW_UI_LINK=${uiLink}`, { flag: 'a' }) - - // Mounts both the repo and the scan-results directory separately - const dockerArgs = [ - 'run', - '--name', - containerName, - '-v', - `${process.cwd()}:/app/src`, - '-v', - `${path.join(process.cwd(), 'scan-results')}:/app/scan-results`, - '--env-file', - envFile, - '-e', - `WORKSPACE=src`, - '-e', - `LW_ACCOUNT=${lwAccount}`, - '-e', - `LW_API_KEY=${lwApiKey}`, - '-e', - `LW_API_SECRET=${lwApiSecret}`, - '-e', - `RUN_SCA=${runSca}`, - '-e', - `RUN_IAC=${runIac}`, - 'lacework/codesec:latest', - 'compare', - ] - - await callCommand('docker', ...dockerArgs) - - // Copy comparison results out - const compareDir = path.join(reportsDir, 'compare') - mkdirSync(compareDir, { recursive: true }) - - // Copy the entire compare directory out + if (runSca) { + const scaDir = path.join(reportsDir, 'sca') + mkdirSync(scaDir, { recursive: true }) await callCommand( 'docker', 'container', 'cp', - `${containerName}:/tmp/scan-results/compare/.`, - compareDir + `${containerName}:/tmp/scan-results/sca/sca-${scanTarget || 'scan'}.sarif`, + path.join(scaDir, `sca-${scanTarget || 'scan'}.sarif`) ) + } - // Verify at least one output was produced - const compareFiles = ['merged-compare.md', 'sca-compare.md', 'iac-compare.md'] - const copied = compareFiles.filter((f) => existsSync(path.join(compareDir, f))) + if (runIac) { + const iacDir = path.join(reportsDir, 'iac') + mkdirSync(iacDir, { recursive: true }) + await callCommand( + 'docker', + 'container', + 'cp', + `${containerName}:/tmp/scan-results/iac/iac-${scanTarget || 'scan'}.json`, + path.join(iacDir, `iac-${scanTarget || 'scan'}.json`) + ) + } - if (copied.length === 0) { - throw new Error('No comparison outputs found in container') - } + await callCommand('docker', 'rm', containerName) + return true +} - // Cleanup container - await callCommand('docker', 'rm', containerName) +export async function runCodesecCompare( + runIac: boolean = false, + runSca: boolean = false +): Promise { + const lwAccount = getRequiredEnvVariable('LW_ACCOUNT') + const lwApiKey = getRequiredEnvVariable('LW_API_KEY') + const lwApiSecret = getRequiredEnvVariable('LW_API_SECRET') + + const containerName = 'codesec-compare' + + info('Running codesec compare') + + const envFile = createEnvFile() + + const uiLink = generateUILink() + writeFileSync(envFile, `\nLW_UI_LINK=${uiLink}`, { flag: 'a' }) + + const dockerArgs = [ + 'run', + '--name', + containerName, + '-v', + `${process.cwd()}:/app/src`, + '-v', + `${path.join(process.cwd(), 'scan-results')}:/app/scan-results`, + '--env-file', + envFile, + '-e', + `WORKSPACE=src`, + '-e', + `LW_ACCOUNT=${lwAccount}`, + '-e', + `LW_API_KEY=${lwApiKey}`, + '-e', + `LW_API_SECRET=${lwApiSecret}`, + '-e', + `RUN_SCA=${runSca}`, + '-e', + `RUN_IAC=${runIac}`, + 'lacework/codesec:latest', + 'compare', + ] + + await callCommand('docker', ...dockerArgs) + + const compareDir = path.join(os.tmpdir(), `codesec-compare-${Date.now()}`) + mkdirSync(compareDir, { recursive: true }) + + await callCommand( + 'docker', + 'container', + 'cp', + `${containerName}:/tmp/scan-results/compare/.`, + compareDir + ) + + await callCommand('docker', 'rm', containerName) + + const mergedPath = path.join(compareDir, 'merged-compare.md') + if (existsSync(mergedPath)) { + return readFileSync(mergedPath, 'utf-8') } - return true + + return null } export function readMarkdownFile(filePath: string): string {