diff --git a/src/main/java/com/checkmarx/jenkins/CheckmarxScanBuilder.java b/src/main/java/com/checkmarx/jenkins/CheckmarxScanBuilder.java index 194757d..57fa131 100644 --- a/src/main/java/com/checkmarx/jenkins/CheckmarxScanBuilder.java +++ b/src/main/java/com/checkmarx/jenkins/CheckmarxScanBuilder.java @@ -356,6 +356,8 @@ public void close() throws IOException { ArtifactArchiver artifactArchiverJson = new ArtifactArchiver(workspace.toURI().relativize(jsonReportFilePath.toURI()).toString()); artifactArchiverJson.perform(run, workspace, envVars, launcher, listener); + saveInArtifactAdditionalReports(scanConfig, workspace, envVars, launcher, listener, run); + } finally { //Deleting temporary directory to clean up the workspace env tempDir.deleteContents(); @@ -368,6 +370,41 @@ public void close() throws IOException { run.setResult(Result.SUCCESS); } + private void saveInArtifactAdditionalReports(ScanConfig scanConfig, FilePath workspace, EnvVars envVars, Launcher launcher, TaskListener listener, Run run) throws IOException, InterruptedException { + if (scanConfig.getAdditionalOptions().contains("--report-format")) { + String additionalOptions = scanConfig.getAdditionalOptions(); + + String formatTypes = extractOptionValue(additionalOptions, "--report-format"); + String[] formats = formatTypes.split(","); + + for (String formatType : formats) { + String fileName = (additionalOptions.contains("--output-name") + ? extractOptionValue(additionalOptions, "--output-name") + : PluginUtils.defaultOutputName) + "." + formatType; + String outputPath = additionalOptions.contains("--output-path") + ? extractOptionValue(additionalOptions, "--output-path") + : "."; + String fullFilePath = new File(outputPath, fileName).getPath(); + FilePath destinationPath = workspace.child(fileName); + + new FilePath(new File(fullFilePath)).copyTo(destinationPath); + + ArtifactArchiver artifactArchiver = new ArtifactArchiver(fileName); + artifactArchiver.perform(run, workspace, envVars, launcher, listener); + } + } + } + + private String extractOptionValue(String options, String optionKey) { + if (options.contains(optionKey)) { + String[] parts = options.split(optionKey, 2); + if (parts.length > 1) { + return parts[1].trim().split(" ")[0]; + } + } + return ""; + } + /** * Return branch name when filled by the user. Otherwise try to pick from environment variables * diff --git a/src/main/java/com/checkmarx/jenkins/PluginUtils.java b/src/main/java/com/checkmarx/jenkins/PluginUtils.java index 2640ea1..55ab37c 100644 --- a/src/main/java/com/checkmarx/jenkins/PluginUtils.java +++ b/src/main/java/com/checkmarx/jenkins/PluginUtils.java @@ -28,6 +28,7 @@ public class PluginUtils { static final String CX_CLIENT_ID_ENV_KEY = "CX_CLIENT_ID"; static final String CX_CLIENT_SECRET_ENV_KEY = "CX_CLIENT_SECRET"; public static final String HTTP_PROXY = "HTTP_PROXY"; + public static final String defaultOutputName = "cx_result"; public static CheckmarxInstallation findCheckmarxInstallation(final String checkmarxInstallation) { final CheckmarxScanBuilder.CheckmarxScanBuilderDescriptor descriptor = Jenkins.get().getDescriptorByType(CheckmarxScanBuilder.CheckmarxScanBuilderDescriptor.class); diff --git a/src/test/java/com/checkmarx/jenkins/CheckmarxScanBuilderTest.java b/src/test/java/com/checkmarx/jenkins/CheckmarxScanBuilderTest.java index 8e9f7af..12ea90e 100644 --- a/src/test/java/com/checkmarx/jenkins/CheckmarxScanBuilderTest.java +++ b/src/test/java/com/checkmarx/jenkins/CheckmarxScanBuilderTest.java @@ -1,11 +1,14 @@ package com.checkmarx.jenkins; - +import java.util.List; +import java.util.Arrays; import hudson.model.FreeStyleBuild; import hudson.model.FreeStyleProject; import hudson.model.Result; +import jenkins.model.ArtifactManager; import org.apache.commons.lang.StringUtils; import org.junit.Test; - +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.util.logging.Logger; public class CheckmarxScanBuilderTest extends CheckmarxTestBase { @@ -103,6 +106,27 @@ public void failWrongCheckmarxInstallation() throws Exception { this.jenkins.assertBuildStatus(Result.FAILURE, build); this.jenkins.assertLogContains("Please configure the build properly and retry.", build); } + @Test + public void CheckmarxScanIsSuccessful_withReportFormat_ArtifactsShouldBeVerified() throws Exception { + log.info("successCheckmarxScanAndVerifyArtifacts"); + + final FreeStyleProject freeStyleProject = createSimpleProject("JenkinsNormalScanWithReport"); + final CheckmarxScanBuilder checkmarxScanBuilder = configureCheckmarxScanBuilder(this.astServerUrl, "JenkinsNormalScan", this.astTenantName, CheckmarxTestBase.BRANCH_MAIN); + checkmarxScanBuilder.setAdditionalOptions("--scan-types iac-security --report-format sarif --output-name reportTest"); + + freeStyleProject.getBuildersList().add(checkmarxScanBuilder); + + final FreeStyleBuild build = freeStyleProject.scheduleBuild2(0).get(); + this.jenkins.assertBuildStatus(Result.SUCCESS, build); + + ArtifactManager artifactManager = build.getArtifactManager(); + assertNotNull("ArtifactManager should not be null", artifactManager); + + List expectedArtifacts = Arrays.asList("reportTest.sarif"); + for (String artifact : expectedArtifacts) { + assertTrue("Artifact " + artifact + " should be present", artifactManager.root().child(artifact).exists()); + } + } @Test public void failIfProjectNameNotProvided() throws Exception { @@ -137,8 +161,17 @@ public void failIfProjectNameNotProvided() throws Exception { */ private void runSuccessCheckmarxScan(String serverUrl, String projectName, String tenant, String branch) throws Exception { final FreeStyleProject freeStyleProject = createSimpleProject("JenkinsNormalScan"); + final CheckmarxScanBuilder checkmarxScanBuilder = configureCheckmarxScanBuilder(serverUrl, projectName, tenant, branch); + checkmarxScanBuilder.setAdditionalOptions("--scan-types iac-security"); - final CheckmarxScanBuilder checkmarxScanBuilder = new CheckmarxScanBuilder(); + freeStyleProject.getBuildersList().add(checkmarxScanBuilder); + + final FreeStyleBuild build = freeStyleProject.scheduleBuild2(0).get(); + this.jenkins.assertBuildStatus(Result.SUCCESS, build); + } + + private CheckmarxScanBuilder configureCheckmarxScanBuilder(String serverUrl, String projectName, String tenant, String branch) { + CheckmarxScanBuilder checkmarxScanBuilder = new CheckmarxScanBuilder(); checkmarxScanBuilder.setUseOwnServerCredentials(true); checkmarxScanBuilder.setProjectName(projectName); checkmarxScanBuilder.setServerUrl(serverUrl); @@ -148,12 +181,8 @@ private void runSuccessCheckmarxScan(String serverUrl, String projectName, Strin checkmarxScanBuilder.setBaseAuthUrl(this.astBaseAuthUrl); checkmarxScanBuilder.setCheckmarxInstallation(CheckmarxTestBase.JT_LATEST); checkmarxScanBuilder.setCredentialsId(CheckmarxTestBase.JENKINS_CREDENTIALS_TOKEN_ID); - checkmarxScanBuilder.setAdditionalOptions("--scan-types sast"); checkmarxScanBuilder.setUseOwnAdditionalOptions(true); - freeStyleProject.getBuildersList().add(checkmarxScanBuilder); - - final FreeStyleBuild build = freeStyleProject.scheduleBuild2(0).get(); - this.jenkins.assertBuildStatus(Result.SUCCESS, build); + return checkmarxScanBuilder; } -} +} \ No newline at end of file