From 57c772736429203767708eb042377f2b30bc0f2a Mon Sep 17 00:00:00 2001 From: Teodor-Ioan Baltoi Date: Tue, 10 Mar 2026 10:33:15 +0000 Subject: [PATCH 1/8] unified scanner docker image unified scanner docker image unified scanner docker image debug + erase macOS runner debug... debug testing clean add back the generateUILink clean added env-file to docker for iac added env-file to docker for iac code-scanning-path argument missed --- .github/workflows/integration-test.yml | 24 +-- action.yaml | 13 -- src/index.ts | 174 +++++++++++------- src/util.ts | 235 ++++++++++++++++++++++--- 4 files changed, 328 insertions(+), 118 deletions(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 458a2243..190bc73e 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -10,28 +10,17 @@ on: workflow_dispatch: env: - LW_ACCOUNT_NAME: ${{ secrets.LW_ACCOUNT_CAT }} - LW_API_KEY: ${{ secrets.LW_API_KEY_CAT }} - LW_API_SECRET: ${{ secrets.LW_API_SECRET_CAT }} + LW_ACCOUNT_NAME: ${{ secrets.LW_ACCOUNT_UEDEMO }} + LW_API_KEY: ${{ secrets.LW_API_KEY_UEDEMO }} + LW_API_SECRET: ${{ secrets.LW_API_SECRET_UEDEMO }} DEBUG: 'true' jobs: build: - strategy: - fail-fast: false - matrix: - os: - - macos-latest - - ubuntu-latest - runs-on: ${{ matrix.os }} + runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Set up Java - uses: actions/setup-java@v3 - with: - distribution: 'temurin' - java-version: '17' - name: Move action run: | mkdir ../action @@ -44,7 +33,6 @@ jobs: target: push sources: ${{ github.workspace }} debug: true - artifact-prefix: ${{ matrix.os }} - name: Check run succeeded env: RUN_OUTPUT: ${{ steps.run-action.outputs.push-completed }} @@ -58,12 +46,12 @@ jobs: - name: Download results uses: actions/download-artifact@v4 with: - name: ${{ matrix.os }}-results-push + name: results-push path: artifact - name: Check results working-directory: artifact run: | - export SCA_RESULTS=`jq '.runs | map (.results | length) | add' sca.sarif` + export SCA_RESULTS=`jq '.runs | map (.results | length) | add' scan-results/sca/sca-scan.sarif` echo "Got $SCA_RESULTS from SCA" if [ "$SCA_RESULTS" -eq 0 ]; then echo "::error::Expected to have $expectedScaResults SCA results!" diff --git a/action.yaml b/action.yaml index 963d01c4..319adce2 100644 --- a/action.yaml +++ b/action.yaml @@ -49,11 +49,6 @@ runs: - if: runner.os == 'Linux' shell: bash run: echo "LACEWORK_START_TIME=$(date --rfc-3339=seconds)" >> $GITHUB_ENV - - if: runner.os == 'macOS' - shell: bash - run: | - brew install coreutils - echo "LACEWORK_START_TIME=$(gdate --rfc-3339=seconds)" >> $GITHUB_ENV - id: init shell: bash env: @@ -63,19 +58,11 @@ runs: echo "Lacework context ID: $LACEWORK_CONTEXT_ID" echo "LACEWORK_CONTEXT_ID=$(echo $LACEWORK_CONTEXT_ID)" >> $GITHUB_ENV echo "LACEWORK_ACTION_REF=$(echo $LACEWORK_ACTION_REF)" >> $GITHUB_ENV - curl https://raw.githubusercontent.com/lacework/go-sdk/main/cli/install.sh | bash - name: Sets LW_LOG var for debug shell: bash if: ${{ inputs.debug == 'true' }} run: | echo "LW_LOG=debug" >> $GITHUB_ENV - - name: Install Lacework CLI component - shell: bash - run: | - lacework --noninteractive -a "${LW_ACCOUNT_NAME}" -k "${LW_API_KEY}" -s "${LW_API_SECRET}" component install sca - lacework --noninteractive -a "${LW_ACCOUNT_NAME}" -k "${LW_API_KEY}" -s "${LW_API_SECRET}" version - env: - CDK_DOWNLOAD_TIMEOUT_MINUTES: 2 - uses: actions/setup-node@v4 with: node-version: 18 diff --git a/src/index.ts b/src/index.ts index c42cc747..4823a2e0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,18 +1,13 @@ import { error, getInput, info, setOutput } from '@actions/core' -import { existsSync, readFileSync } from 'fs' +import { copyFileSync, existsSync, mkdirSync } from 'fs' +import * as path from 'path' import { downloadArtifact, postCommentIfInPr, resolveExistingCommentIfFound, uploadArtifact, } from './actions' -import { callLaceworkCli, debug, generateUILink, getOptionalEnvVariable } from './util' - -import path from 'path' - -const artifactPrefix = getInput('artifact-prefix') -const sarifReportPath = getInput('code-scanning-path') -const comparisonMarkdownPath = 'comparison.md' +import { callCommand, codesecRun, getOptionalEnvVariable, readMarkdownFile } from './util' async function runAnalysis() { const target = getInput('target') @@ -30,87 +25,132 @@ async function runAnalysis() { info('Analyzing ' + target) const toUpload: string[] = [] - // command to print both sarif and lwjson formats - var args = ['scan', '.', '--formats', 'sarif', '--output', sarifReportPath, '--deployment', 'ci'] - if (target === 'push') { - args.push('--save-results') + // Run codesec Docker scanner + // targetScan: 'new'/'old' for PR mode, 'scan' for push mode (should upload results to db) + var targetScan = target + if (target == 'push') { + targetScan = 'scan' } - if (debug()) { - args.push('--debug') + const resultsPath = await codesecRun('scan', true, true, targetScan) + + // Upload SCA SARIF from the returned results path + const scaSarifFile = path.join(resultsPath, 'sca', `sca-${targetScan}.sarif`) + if (existsSync(scaSarifFile)) { + info(`Found SCA SARIF file to upload: ${scaSarifFile}`) + toUpload.push(scaSarifFile) + + // Copy SARIF to code-scanning-path for backward compatibility + const codeScanningPath = getInput('code-scanning-path') + if (codeScanningPath) { + info(`Copying SARIF to code-scanning-path: ${codeScanningPath}`) + copyFileSync(scaSarifFile, codeScanningPath) + } + } else { + info(`SCA SARIF file not found at: ${scaSarifFile}`) } - await callLaceworkCli(...args) - toUpload.push(sarifReportPath) - const uploadStart = Date.now() + // Upload IAC JSON from the returned results path + const iacJsonFile = path.join(resultsPath, 'iac', `iac-${targetScan}.json`) + if (existsSync(iacJsonFile)) { + info(`Found IAC JSON file to upload: ${iacJsonFile}`) + toUpload.push(iacJsonFile) + } else { + info(`IAC JSON file not found at: ${iacJsonFile}`) + } - await uploadArtifact(getArtifactName(target), ...toUpload) + const artifactPrefix = getInput('artifact-prefix') + const artifactName = + artifactPrefix !== '' ? artifactPrefix + '-results-' + target : 'results-' + target + info(`Uploading artifact '${artifactName}' with ${toUpload.length} file(s)`) + await uploadArtifact(artifactName, ...toUpload) setOutput(`${target}-completed`, true) } -export async function compareResults(oldReport: string, newReport: string): Promise { - const args = [ - 'compare', - '--old', - oldReport, - '--new', - newReport, - '--output', - sarifReportPath, - '--markdown', - comparisonMarkdownPath, - '--markdown-variant', - 'GitHub', - '--deployment', - 'ci', - ] - const uiLink = generateUILink() - if (uiLink) args.push(...['--ui-link', uiLink]) - if (debug()) args.push('--debug') +async function displayResults() { + info('Displaying results') - await callLaceworkCli(...args) - await uploadArtifact(getArtifactName('compare'), sarifReportPath, comparisonMarkdownPath) + // Download artifacts from previous jobs + const artifactOld = await downloadArtifact('results-old') + const artifactNew = await downloadArtifact('results-new') - return existsSync(comparisonMarkdownPath) ? readFileSync(comparisonMarkdownPath, 'utf8') : '' -} + // Create local scan-results directory for compare + mkdirSync('scan-results/sca', { recursive: true }) + mkdirSync('scan-results/iac', { recursive: true }) -async function displayResults() { - info('Displaying results') - const downloadStart = Date.now() - const artifactOld = await downloadArtifact(getArtifactName('old')) - const artifactNew = await downloadArtifact(getArtifactName('new')) - const sarifFileOld = path.join(artifactOld, sarifReportPath) - const sarifFileNew = path.join(artifactNew, sarifReportPath) - - var compareMessage: string - if (existsSync(sarifFileOld) && existsSync(sarifFileNew)) { - compareMessage = await compareResults(sarifFileOld, sarifFileNew) - } else { - throw new Error('SARIF file not found') + // Check and copy files for each scanner type + const scaAvailable = await prepareScannerFiles('sca', artifactOld, artifactNew) + const iacAvailable = await prepareScannerFiles('iac', artifactOld, artifactNew) + + // Need at least one scanner to compare + if (!scaAvailable && !iacAvailable) { + info('No scanner files available for comparison. Nothing to compare.') + setOutput('display-completed', true) + return } - const commentStart = Date.now() - if (compareMessage.length > 0 && getInput('token').length > 0) { - info('Posting comment to GitHub PR as there were new issues introduced:') - if (getInput('footer') !== '') { - compareMessage += '\n\n' + getInput('footer') + // Run codesec compare mode with available scanners + await codesecRun('compare', iacAvailable, 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 } - info(compareMessage) - const commentUrl = await postCommentIfInPr(compareMessage) + } + + if (!message) { + info('No comparison output produced. No changes detected.') + setOutput('display-completed', true) + return + } + + // Check if there are new violations (non-zero count in "Found N new potential violations") + const hasViolations = /Found\s+[1-9]\d*\s+/.test(message) + + if (hasViolations && getInput('token').length > 0) { + info('Posting comment to GitHub PR as there were new issues introduced') + const commentUrl = await postCommentIfInPr(message) if (commentUrl !== undefined) { setOutput('posted-comment', commentUrl) } } else { + // No new violations or no token - resolve existing comment if found await resolveExistingCommentIfFound() } - setOutput(`display-completed`, true) + + setOutput('display-completed', true) } -function getArtifactName(target: string): string { - var artifactName = 'results-' - if (artifactPrefix !== '') { - artifactName = artifactPrefix + '-' + artifactName +async function prepareScannerFiles( + scanner: 'sca' | 'iac', + artifactOld: string, + artifactNew: string +): Promise { + const ext = scanner === 'sca' ? 'sarif' : 'json' + const oldPath = path.join(artifactOld, 'scan-results', scanner, `${scanner}-old.${ext}`) + const newPath = path.join(artifactNew, 'scan-results', scanner, `${scanner}-new.${ext}`) + + const oldExists = existsSync(oldPath) + const newExists = existsSync(newPath) + + if (!oldExists || !newExists) { + info(`${scanner.toUpperCase()} files not found for compare. old=${oldExists}, new=${newExists}`) + return false } - return artifactName + target + + info(`Copying ${scanner.toUpperCase()} files for compare`) + await callCommand('cp', oldPath, path.join('scan-results', scanner, `${scanner}-old.${ext}`)) + await callCommand('cp', newPath, path.join('scan-results', scanner, `${scanner}-new.${ext}`)) + return true } async function main() { diff --git a/src/util.ts b/src/util.ts index b432e53a..1615ebe5 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,7 +1,31 @@ import { error, getInput, info, isDebug } from '@actions/core' import { context } from '@actions/github' import { spawn } from 'child_process' -import { readFileSync } from 'fs' +import { readFileSync, mkdirSync, writeFileSync } from 'fs' +import * as os from 'os' +import * as path from 'path' + +// Gather GITHUB_* and CI env vars for the lacework iac binary to read directly +function gatherGitHubEnvVars(): string[] { + const prefixes = ['GITHUB_', 'CI'] + const envVars: string[] = [] + + for (const [key, value] of Object.entries(process.env)) { + if (prefixes.some((p) => key.startsWith(p))) { + envVars.push(`${key}=${value}`) + } + } + info('Env vars passed to container: ' + envVars.map((v) => v.split('=')[0]).join(', ')) + return envVars +} + +// Create a temp env file with GitHub CI vars for --env-file +function createEnvFile(): string { + const envFile = path.join(os.tmpdir(), `codesec-env-${Date.now()}.list`) + const envVars = gatherGitHubEnvVars() + writeFileSync(envFile, envVars.join('\n')) + return envFile +} export function getMsSinceStart(): string { const now = Date.now() @@ -59,25 +83,6 @@ export function getOptionalEnvVariable(name: string, defaultValue: string) { return value } -export async function callLaceworkCli(...args: string[]) { - const accountName = getRequiredEnvVariable('LW_ACCOUNT_NAME') - const apiKey = getRequiredEnvVariable('LW_API_KEY') - const apiSecret = getRequiredEnvVariable('LW_API_SECRET') - const expandedArgs = [ - '--noninteractive', - '--account', - accountName, - '--api_key', - apiKey, - '--api_secret', - apiSecret, - 'sca', - ...args, - ] - info('Calling lacework ' + expandedArgs.join(' ')) - await callCommand('lacework', ...expandedArgs) -} - export function getOrDefault(name: string, defaultValue: string) { const setTo = getInput(name) if (setTo !== undefined && setTo.length > 0) return setTo @@ -108,3 +113,193 @@ export function generateUILink() { return url } + +// codesecRun - 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 codesecRun( + action: string, + runIac: boolean = false, + runSca: boolean = false, + scanTarget?: string +): Promise { + const lwAccount = getRequiredEnvVariable('LW_ACCOUNT_NAME') + const lwApiKey = getRequiredEnvVariable('LW_API_KEY') + const lwApiSecret = getRequiredEnvVariable('LW_API_SECRET') + + // Create scan-results directory + const reportsDir = path.join(process.cwd(), 'scan-results') + + 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'}`, + '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`) + ) + } + + 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`) + ) + } + + // 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() + + // 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 all available comparison outputs + // merged-compare.md exists when both SCA and IAC comparisons succeed + // sca-compare.md / iac-compare.md exist for individual comparisons + let copiedAny = false + + try { + await callCommand( + 'docker', + 'container', + 'cp', + `${containerName}:/tmp/scan-results/compare/merged-compare.md`, + path.join(compareDir, 'merged-compare.md') + ) + copiedAny = true + } catch { + info('Merged compare output not found (partial compare mode)') + } + + try { + await callCommand( + 'docker', + 'container', + 'cp', + `${containerName}:/tmp/scan-results/compare/sca-compare.md`, + path.join(compareDir, 'sca-compare.md') + ) + copiedAny = true + } catch { + info('SCA compare output not found (may have been skipped)') + } + + try { + await callCommand( + 'docker', + 'container', + 'cp', + `${containerName}:/tmp/scan-results/compare/iac-compare.md`, + path.join(compareDir, 'iac-compare.md') + ) + copiedAny = true + } catch { + info('IAC compare output not found (may have been skipped)') + } + + if (!copiedAny) { + throw new Error('No comparison outputs found in container') + } + + // Cleanup container + await callCommand('docker', 'rm', containerName) + } + return reportsDir +} + +export function readMarkdownFile(filePath: string): string { + try { + return readFileSync(filePath, 'utf-8') + } catch (error) { + throw new Error(`Failed to read scanner output file: ${error}`) + } +} From 4bcf05db602641d60f6ee428c50335ea59112321 Mon Sep 17 00:00:00 2001 From: Teodor-Ioan Baltoi Date: Mon, 23 Mar 2026 13:53:08 +0000 Subject: [PATCH 2/8] disable iac scanning for now disable iac scanning for now --- src/index.ts | 62 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/src/index.ts b/src/index.ts index 4823a2e0..6de84fe9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,10 @@ import { } from './actions' import { callCommand, codesecRun, getOptionalEnvVariable, readMarkdownFile } from './util' +// Global scanner toggles - set to false to disable a scanner globally +const enableScaRunning = true +const enableIacRunning = false // TODO: change to true when ready + async function runAnalysis() { const target = getInput('target') @@ -31,31 +35,35 @@ async function runAnalysis() { if (target == 'push') { targetScan = 'scan' } - const resultsPath = await codesecRun('scan', true, true, targetScan) + const resultsPath = await codesecRun('scan', enableIacRunning, enableScaRunning, targetScan) // Upload SCA SARIF from the returned results path - const scaSarifFile = path.join(resultsPath, 'sca', `sca-${targetScan}.sarif`) - if (existsSync(scaSarifFile)) { - info(`Found SCA SARIF file to upload: ${scaSarifFile}`) - toUpload.push(scaSarifFile) - - // Copy SARIF to code-scanning-path for backward compatibility - const codeScanningPath = getInput('code-scanning-path') - if (codeScanningPath) { - info(`Copying SARIF to code-scanning-path: ${codeScanningPath}`) - copyFileSync(scaSarifFile, codeScanningPath) + if (enableScaRunning) { + const scaSarifFile = path.join(resultsPath, 'sca', `sca-${targetScan}.sarif`) + if (existsSync(scaSarifFile)) { + info(`Found SCA SARIF file to upload: ${scaSarifFile}`) + toUpload.push(scaSarifFile) + + // Copy SARIF to code-scanning-path for backward compatibility + const codeScanningPath = getInput('code-scanning-path') + if (codeScanningPath) { + info(`Copying SARIF to code-scanning-path: ${codeScanningPath}`) + copyFileSync(scaSarifFile, codeScanningPath) + } + } else { + info(`SCA SARIF file not found at: ${scaSarifFile}`) } - } else { - info(`SCA SARIF file not found at: ${scaSarifFile}`) } // Upload IAC JSON from the returned results path - const iacJsonFile = path.join(resultsPath, 'iac', `iac-${targetScan}.json`) - if (existsSync(iacJsonFile)) { - info(`Found IAC JSON file to upload: ${iacJsonFile}`) - toUpload.push(iacJsonFile) - } else { - info(`IAC JSON file not found at: ${iacJsonFile}`) + if (enableIacRunning) { + const iacJsonFile = path.join(resultsPath, 'iac', `iac-${targetScan}.json`) + if (existsSync(iacJsonFile)) { + info(`Found IAC JSON file to upload: ${iacJsonFile}`) + toUpload.push(iacJsonFile) + } else { + info(`IAC JSON file not found at: ${iacJsonFile}`) + } } const artifactPrefix = getInput('artifact-prefix') @@ -74,12 +82,18 @@ async function displayResults() { const artifactNew = await downloadArtifact('results-new') // Create local scan-results directory for compare - mkdirSync('scan-results/sca', { recursive: true }) - mkdirSync('scan-results/iac', { recursive: true }) + if (enableScaRunning) { + mkdirSync('scan-results/sca', { recursive: true }) + } + if (enableIacRunning) { + mkdirSync('scan-results/iac', { recursive: true }) + } // Check and copy files for each scanner type - const scaAvailable = await prepareScannerFiles('sca', artifactOld, artifactNew) - const iacAvailable = await prepareScannerFiles('iac', artifactOld, artifactNew) + const scaAvailable = + enableScaRunning && (await prepareScannerFiles('sca', artifactOld, artifactNew)) + const iacAvailable = + enableIacRunning && (await prepareScannerFiles('iac', artifactOld, artifactNew)) // Need at least one scanner to compare if (!scaAvailable && !iacAvailable) { @@ -89,7 +103,7 @@ async function displayResults() { } // Run codesec compare mode with available scanners - await codesecRun('compare', iacAvailable, scaAvailable) + await codesecRun('compare', enableIacRunning && iacAvailable, enableScaRunning && scaAvailable) // Read comparison output - check all possible outputs const outputs = [ From 2d481fc24fbe36c161a7c14de97e4a707c16d1ae Mon Sep 17 00:00:00 2001 From: Teodor-Ioan Baltoi Date: Mon, 23 Mar 2026 14:14:05 +0000 Subject: [PATCH 3/8] check older credentials --- .github/workflows/integration-test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 190bc73e..cf4a6228 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -10,9 +10,9 @@ on: workflow_dispatch: env: - LW_ACCOUNT_NAME: ${{ secrets.LW_ACCOUNT_UEDEMO }} - LW_API_KEY: ${{ secrets.LW_API_KEY_UEDEMO }} - LW_API_SECRET: ${{ secrets.LW_API_SECRET_UEDEMO }} + LW_ACCOUNT_NAME: ${{ secrets.LW_ACCOUNT_CAT }} + LW_API_KEY: ${{ secrets.LW_API_KEY_CAT }} + LW_API_SECRET: ${{ secrets.LW_API_SECRET_CAT }} DEBUG: 'true' jobs: From 15cf6bd703a4148c781aeb8e421b44d7923c5e1b Mon Sep 17 00:00:00 2001 From: Teodor-Ioan Baltoi Date: Tue, 24 Mar 2026 15:44:06 +0000 Subject: [PATCH 4/8] same integration test file --- .github/workflows/integration-test.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 8d78220e..26356dfc 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -60,9 +60,13 @@ jobs: - name: Check results working-directory: artifact run: | - export SCA_RESULTS=`jq '.runs | map (.results | length) | add' scan-results/sca/sca-scan.sarif` - echo "Got $SCA_RESULTS from SCA" - if [ "$SCA_RESULTS" -eq 0 ]; then - echo "::error::Expected to have $expectedScaResults SCA results!" - exit 1 + if [ -f scanning-report.sarif ]; then + export expectedScaResults=9 + export SCA_RESULTS=`jq '.runs | map (.results | length) | add' scanning-report.sarif` + if [ "$SCA_RESULTS" -eq $expectedScaResults ]; then + echo "Found expected number of SCA results: $SCA_RESULTS" + else + echo "::error::Expected to have $expectedScaResults SCA results!" + exit 1 + fi fi From 14dcd8eb17a38a6b3ff4bdd6a3f5cf303333576c Mon Sep 17 00:00:00 2001 From: Teodor-Ioan Baltoi Date: Tue, 24 Mar 2026 15:50:34 +0000 Subject: [PATCH 5/8] integration with UEDEMO --- .github/workflows/integration-test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 26356dfc..e03eb075 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -10,9 +10,9 @@ on: workflow_dispatch: env: - LW_ACCOUNT_NAME: ${{ secrets.LW_ACCOUNT_CAT }} - LW_API_KEY: ${{ secrets.LW_API_KEY_CAT }} - LW_API_SECRET: ${{ secrets.LW_API_SECRET_CAT }} + LW_ACCOUNT_NAME: ${{ secrets.LW_ACCOUNT_UEDEMO }} + LW_API_KEY: ${{ secrets.LW_API_KEY_UEDEMO }} + LW_API_SECRET: ${{ secrets.LW_API_SECRET_UEDEMO }} DEBUG: true jobs: From f0c8e7b81d57127dea8494fd9f966e3653642a99 Mon Sep 17 00:00:00 2001 From: Teodor-Ioan Baltoi Date: Wed, 25 Mar 2026 14:20:33 +0000 Subject: [PATCH 6/8] try uedemo again... --- .github/workflows/integration-test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 981a5234..a5867f66 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -10,9 +10,9 @@ on: workflow_dispatch: env: - LW_ACCOUNT: ${{ secrets.LW_ACCOUNT_CAT }} - LW_API_KEY: ${{ secrets.LW_API_KEY_CAT }} - LW_API_SECRET: ${{ secrets.LW_API_SECRET_CAT }} + LW_ACCOUNT: ${{ secrets.LW_ACCOUNT_UEDEMO }} + LW_API_KEY: ${{ secrets.LW_API_KEY_UEDEMO }} + LW_API_SECRET: ${{ secrets.LW_API_SECRET_UEDEMO }} DEBUG: true jobs: From 8a50c3156f7d940b545300704b7892078c0e2047 Mon Sep 17 00:00:00 2001 From: Teodor-Ioan Baltoi Date: Wed, 25 Mar 2026 15:00:17 +0000 Subject: [PATCH 7/8] remove redundant conditional --- action.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/action.yaml b/action.yaml index 66283dd9..5030c956 100644 --- a/action.yaml +++ b/action.yaml @@ -46,8 +46,7 @@ outputs: runs: using: 'composite' steps: - - if: runner.os == 'Linux' - shell: bash + - shell: bash run: echo "LACEWORK_START_TIME=$(date --rfc-3339=seconds)" >> $GITHUB_ENV - id: init shell: bash From a163fbb5a321df6f7623ca7b4fe3aae06af06197 Mon Sep 17 00:00:00 2001 From: Teodor-Ioan Baltoi Date: Thu, 26 Mar 2026 09:38:27 +0000 Subject: [PATCH 8/8] switch back to CAT --- .github/workflows/integration-test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index a5867f66..981a5234 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -10,9 +10,9 @@ on: workflow_dispatch: env: - LW_ACCOUNT: ${{ secrets.LW_ACCOUNT_UEDEMO }} - LW_API_KEY: ${{ secrets.LW_API_KEY_UEDEMO }} - LW_API_SECRET: ${{ secrets.LW_API_SECRET_UEDEMO }} + LW_ACCOUNT: ${{ secrets.LW_ACCOUNT_CAT }} + LW_API_KEY: ${{ secrets.LW_API_KEY_CAT }} + LW_API_SECRET: ${{ secrets.LW_API_SECRET_CAT }} DEBUG: true jobs: