From 25eea51b17e9dbf9affa44c81f103c2ed7e4ad1a Mon Sep 17 00:00:00 2001 From: miryamfoiferCX Date: Wed, 30 Oct 2024 12:50:08 +0200 Subject: [PATCH 01/16] 1. adding code-repository optional parameter 2. support PR decoration command for github & gitlab on-prem --- internal/commands/util/pr.go | 30 +++++++++++++++++++++++++++++- internal/params/flags.go | 2 ++ internal/wrappers/pr.go | 2 ++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/internal/commands/util/pr.go b/internal/commands/util/pr.go index 6c243e0d1..ae56cf833 100644 --- a/internal/commands/util/pr.go +++ b/internal/commands/util/pr.go @@ -23,6 +23,10 @@ const ( resultPolicyDefaultTimeout = 1 failedGettingScanError = "Failed showing a scan" noPRDecorationCreated = "A PR couldn't be created for this scan because it is still in progress." + githubOnPremURLSuffix = "/api/v3/repos/" + gitlabOnPremURLSuffix = "/api/v4/" + githubCloudUrl = "https://api.github.com/repos/" + gitlabCloudUrl = "https://gitlab.com" + gitlabOnPremURLSuffix ) func NewPRDecorationCommand(prWrapper wrappers.PRWrapper, policyWrapper wrappers.PolicyWrapper, scansWrapper wrappers.ScansWrapper) *cobra.Command { @@ -93,6 +97,7 @@ func PRDecorationGithub(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Pol RunE: runPRDecoration(prWrapper, policyWrapper, scansWrapper), } + prDecorationGithub.Flags().String(params.CodeRepositoryFlag, "", params.CodeRepositoryFlagUsage) prDecorationGithub.Flags().String(params.ScanIDFlag, "", "Scan ID to retrieve results from") prDecorationGithub.Flags().String(params.SCMTokenFlag, "", params.GithubTokenUsage) prDecorationGithub.Flags().String(params.NamespaceFlag, "", fmt.Sprintf(params.NamespaceFlagUsage, "Github")) @@ -120,7 +125,7 @@ func PRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Pol Example: heredoc.Doc( ` $ cx utils pr gitlab --scan-id --token --namespace --repo-name - --iid --gitlab-project + --iid --gitlab-project --code-repository-url `, ), Annotations: map[string]string{ @@ -132,6 +137,7 @@ func PRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Pol RunE: runPRDecorationGitlab(prWrapper, policyWrapper, scansWrapper), } + prDecorationGitlab.Flags().String(params.CodeRepositoryFlag, "", params.CodeRepositoryFlagUsage) prDecorationGitlab.Flags().String(params.ScanIDFlag, "", "Scan ID to retrieve results from") prDecorationGitlab.Flags().String(params.SCMTokenFlag, "", params.GitLabTokenUsage) prDecorationGitlab.Flags().String(params.NamespaceFlag, "", fmt.Sprintf(params.NamespaceFlagUsage, "Gitlab")) @@ -160,6 +166,7 @@ func runPRDecoration(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Policy namespaceFlag, _ := cmd.Flags().GetString(params.NamespaceFlag) repoNameFlag, _ := cmd.Flags().GetString(params.RepoNameFlag) prNumberFlag, _ := cmd.Flags().GetInt(params.PRNumberFlag) + apiURL, _ := cmd.Flags().GetString(params.CodeRepositoryFlag) scanRunningOrQueued, err := isScanRunningOrQueued(scansWrapper, scanID) @@ -179,6 +186,8 @@ func runPRDecoration(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Policy } // Build and post the pr decoration + updatedApiURL := updateApiURLForGithubOnPrem(apiURL) + prModel := &wrappers.PRModel{ ScanID: scanID, ScmToken: scmTokenFlag, @@ -186,6 +195,7 @@ func runPRDecoration(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Policy RepoName: repoNameFlag, PrNumber: prNumberFlag, Policies: policies, + ApiURL: updatedApiURL, } prResponse, errorModel, err := prWrapper.PostPRDecoration(prModel) if err != nil { @@ -202,6 +212,20 @@ func runPRDecoration(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Policy } } +func updateApiURLForGithubOnPrem(apiURL string) string { + if apiURL != "" { + return apiURL + githubOnPremURLSuffix + } + return githubCloudUrl +} + +func updateApiURLForGitlabOnPrem(apiURL string) string { + if apiURL != "" { + return apiURL + gitlabOnPremURLSuffix + } + return gitlabCloudUrl +} + func runPRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers.PolicyWrapper, scansWrapper wrappers.ScansWrapper) func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { scanID, _ := cmd.Flags().GetString(params.ScanIDFlag) @@ -210,6 +234,7 @@ func runPRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers. repoNameFlag, _ := cmd.Flags().GetString(params.RepoNameFlag) iIDFlag, _ := cmd.Flags().GetInt(params.PRIidFlag) gitlabProjectIDFlag, _ := cmd.Flags().GetInt(params.PRGitlabProjectFlag) + apiURL, _ := cmd.Flags().GetString(params.CodeRepositoryFlag) scanRunningOrQueued, err := isScanRunningOrQueued(scansWrapper, scanID) @@ -229,6 +254,8 @@ func runPRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers. } // Build and post the mr decoration + updatedApiURL := updateApiURLForGitlabOnPrem(apiURL) + prModel := &wrappers.GitlabPRModel{ ScanID: scanID, ScmToken: scmTokenFlag, @@ -237,6 +264,7 @@ func runPRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers. IiD: iIDFlag, GitlabProjectID: gitlabProjectIDFlag, Policies: policies, + ApiURL: updatedApiURL, } prResponse, errorModel, err := prWrapper.PostGitlabPRDecoration(prModel) diff --git a/internal/params/flags.go b/internal/params/flags.go index 6bd011ec8..76007460a 100644 --- a/internal/params/flags.go +++ b/internal/params/flags.go @@ -33,6 +33,8 @@ const ( BranchFlag = "branch" BranchFlagSh = "b" ScanIDFlag = "scan-id" + CodeRepositoryFlag = "code-repository-url" + CodeRepositoryFlagUsage = "Code repository URL (optional for self-hosted Azure DevOps)" BranchFlagUsage = "Branch to scan" MainBranchFlag = "branch" ScaResolverFlag = "sca-resolver" diff --git a/internal/wrappers/pr.go b/internal/wrappers/pr.go index 1a6fb0cbf..311f76c53 100644 --- a/internal/wrappers/pr.go +++ b/internal/wrappers/pr.go @@ -11,6 +11,7 @@ type PRModel struct { RepoName string `json:"repoName"` PrNumber int `json:"prNumber"` Policies []PrPolicy `json:"violatedPolicyList"` + ApiURL string `json:"apiUrl"` } type GitlabPRModel struct { @@ -21,6 +22,7 @@ type GitlabPRModel struct { IiD int `json:"iid"` GitlabProjectID int `json:"gitlabProjectID"` Policies []PrPolicy `json:"violatedPolicyList"` + ApiURL string `json:"apiUrl"` } type PRWrapper interface { From 2158f149633429f58561fa7d17b4157879e4fea8 Mon Sep 17 00:00:00 2001 From: miryamfoiferCX Date: Wed, 30 Oct 2024 13:04:05 +0200 Subject: [PATCH 02/16] support 2 tasks in PR title --- .github/workflows/pr-linter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-linter.yml b/.github/workflows/pr-linter.yml index 01aa69cae..5b48260b6 100644 --- a/.github/workflows/pr-linter.yml +++ b/.github/workflows/pr-linter.yml @@ -18,7 +18,7 @@ jobs: exit 1 fi - if ! [[ "$PR_TITLE" =~ \(AST-[0-9]+\)$ ]]; then + if ! [[ "$PR_TITLE" =~ \(AST-[0-9]+\)$ || "$PR_TITLE" =~ \(AST-[0-9]+(, AST-[0-9]+)*\)$ ]]; then echo "::error::PR title must contain a Jira ticket ID at the end in the format '(AST-XXXX)'." exit 1 fi From d602b2f42b15810d805f7aa75a8014a4b7e52a27 Mon Sep 17 00:00:00 2001 From: miryamfoiferCX Date: Wed, 30 Oct 2024 15:06:52 +0200 Subject: [PATCH 03/16] fixes for linter, adding UT, update base image --- Dockerfile | 2 +- internal/commands/util/pr.go | 20 ++++++++++---------- internal/commands/util/pr_test.go | 22 ++++++++++++++++++++++ internal/wrappers/pr.go | 4 ++-- 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/Dockerfile b/Dockerfile index 47c1ef014..bb61ceb48 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM cgr.dev/chainguard/bash@sha256:f8e48690d991e6814c81f063833176439e8f0d4bc1c5f0a47f94858dea3e4f44 +FROM cgr.dev/chainguard/bash@sha256:e1d16dec8d976859080d984167109b3557c2b6494f10be08147806b78bdef691 USER nonroot COPY cx /app/bin/cx diff --git a/internal/commands/util/pr.go b/internal/commands/util/pr.go index ae56cf833..f141d3632 100644 --- a/internal/commands/util/pr.go +++ b/internal/commands/util/pr.go @@ -25,8 +25,8 @@ const ( noPRDecorationCreated = "A PR couldn't be created for this scan because it is still in progress." githubOnPremURLSuffix = "/api/v3/repos/" gitlabOnPremURLSuffix = "/api/v4/" - githubCloudUrl = "https://api.github.com/repos/" - gitlabCloudUrl = "https://gitlab.com" + gitlabOnPremURLSuffix + githubCloudURL = "https://api.github.com/repos/" + gitlabCloudURL = "https://gitlab.com" + gitlabOnPremURLSuffix ) func NewPRDecorationCommand(prWrapper wrappers.PRWrapper, policyWrapper wrappers.PolicyWrapper, scansWrapper wrappers.ScansWrapper) *cobra.Command { @@ -186,7 +186,7 @@ func runPRDecoration(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Policy } // Build and post the pr decoration - updatedApiURL := updateApiURLForGithubOnPrem(apiURL) + updatedAPIURL := updateAPIURLForGithubOnPrem(apiURL) prModel := &wrappers.PRModel{ ScanID: scanID, @@ -195,7 +195,7 @@ func runPRDecoration(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Policy RepoName: repoNameFlag, PrNumber: prNumberFlag, Policies: policies, - ApiURL: updatedApiURL, + APIURL: updatedAPIURL, } prResponse, errorModel, err := prWrapper.PostPRDecoration(prModel) if err != nil { @@ -212,18 +212,18 @@ func runPRDecoration(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Policy } } -func updateApiURLForGithubOnPrem(apiURL string) string { +func updateAPIURLForGithubOnPrem(apiURL string) string { if apiURL != "" { return apiURL + githubOnPremURLSuffix } - return githubCloudUrl + return githubCloudURL } -func updateApiURLForGitlabOnPrem(apiURL string) string { +func updateAPIURLForGitlabOnPrem(apiURL string) string { if apiURL != "" { return apiURL + gitlabOnPremURLSuffix } - return gitlabCloudUrl + return gitlabCloudURL } func runPRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers.PolicyWrapper, scansWrapper wrappers.ScansWrapper) func(cmd *cobra.Command, args []string) error { @@ -254,7 +254,7 @@ func runPRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers. } // Build and post the mr decoration - updatedApiURL := updateApiURLForGitlabOnPrem(apiURL) + updatedAPIURL := updateAPIURLForGitlabOnPrem(apiURL) prModel := &wrappers.GitlabPRModel{ ScanID: scanID, @@ -264,7 +264,7 @@ func runPRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers. IiD: iIDFlag, GitlabProjectID: gitlabProjectIDFlag, Policies: policies, - ApiURL: updatedApiURL, + APIURL: updatedAPIURL, } prResponse, errorModel, err := prWrapper.PostGitlabPRDecoration(prModel) diff --git a/internal/commands/util/pr_test.go b/internal/commands/util/pr_test.go index f2a86ae29..eed8d35e5 100644 --- a/internal/commands/util/pr_test.go +++ b/internal/commands/util/pr_test.go @@ -44,3 +44,25 @@ func TestPRDecorationGithub_WhenNoViolatedPolicies_ShouldNotReturnPolicy(t *test prPolicy := policiesToPrPolicies(policyResponse) asserts.True(t, len(prPolicy) == 0) } + +func TestUpdateAPIURLForGithubOnPrem_whenAPIURLIsSet_ShouldUpdateAPIURL(t *testing.T) { + selfHostedURL := "https://github.example.com" + updatedAPIURL := updateAPIURLForGithubOnPrem(selfHostedURL) + asserts.Equal(t, selfHostedURL+githubOnPremURLSuffix, updatedAPIURL) +} + +func TestUpdateAPIURLForGithubOnPrem_whenAPIURLIsNotSet_ShouldReturnCloudAPIURL(t *testing.T) { + cloudAPIURL := updateAPIURLForGithubOnPrem("") + asserts.Equal(t, githubCloudURL, cloudAPIURL) +} + +func TestUpdateAPIURLForGitlabOnPrem_whenAPIURLIsSet_ShouldUpdateAPIURL(t *testing.T) { + selfHostedURL := "https://gitlab.example.com" + updatedAPIURL := updateAPIURLForGitlabOnPrem(selfHostedURL) + asserts.Equal(t, selfHostedURL+gitlabOnPremURLSuffix, updatedAPIURL) +} + +func TestUpdateAPIURLForGitlabOnPrem_whenAPIURLIsNotSet_ShouldReturnCloudAPIURL(t *testing.T) { + cloudAPIURL := updateAPIURLForGitlabOnPrem("") + asserts.Equal(t, gitlabCloudURL, cloudAPIURL) +} diff --git a/internal/wrappers/pr.go b/internal/wrappers/pr.go index 311f76c53..40ccdb159 100644 --- a/internal/wrappers/pr.go +++ b/internal/wrappers/pr.go @@ -11,7 +11,7 @@ type PRModel struct { RepoName string `json:"repoName"` PrNumber int `json:"prNumber"` Policies []PrPolicy `json:"violatedPolicyList"` - ApiURL string `json:"apiUrl"` + APIURL string `json:"apiUrl"` } type GitlabPRModel struct { @@ -22,7 +22,7 @@ type GitlabPRModel struct { IiD int `json:"iid"` GitlabProjectID int `json:"gitlabProjectID"` Policies []PrPolicy `json:"violatedPolicyList"` - ApiURL string `json:"apiUrl"` + APIURL string `json:"apiUrl"` } type PRWrapper interface { From d9ba126364d7bbedb81adfd25287000615ef8ac8 Mon Sep 17 00:00:00 2001 From: miryamfoiferCX Date: Thu, 31 Oct 2024 14:44:40 +0200 Subject: [PATCH 04/16] add unit-integration tests --- go.mod | 1 + internal/commands/util/pr_test.go | 4 +- test/integration/pr_test.go | 92 ++++++++++++++++++++++++++++++- 3 files changed, 93 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 7e2afcca5..62374c859 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/Checkmarx/gen-ai-prompts v0.0.0-20240807143411-708ceec12b63 github.com/CheckmarxDev/containers-resolver v1.0.13 github.com/MakeNowJust/heredoc v1.0.0 + github.com/bouk/monkey v1.0.0 github.com/checkmarxDev/gpt-wrapper v0.0.0-20230721160222-85da2fd1cc4c github.com/golang-jwt/jwt v3.2.2+incompatible github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 diff --git a/internal/commands/util/pr_test.go b/internal/commands/util/pr_test.go index eed8d35e5..5d02a240d 100644 --- a/internal/commands/util/pr_test.go +++ b/internal/commands/util/pr_test.go @@ -24,14 +24,14 @@ func TestNewMRDecorationCommandMustExist(t *testing.T) { assert.ErrorContains(t, err, "scan-id") } -func TestIfScanRunning_WhenScanRunning_ShouldReturnTrue(t *testing.T) { +func TestIsScanRunning_WhenScanRunning_ShouldReturnTrue(t *testing.T) { scansMockWrapper := &mock.ScansMockWrapper{Running: true} scanRunning, _ := isScanRunningOrQueued(scansMockWrapper, "ScanRunning") asserts.True(t, scanRunning) } -func TestIfScanRunning_WhenScanDone_ShouldReturnFalse(t *testing.T) { +func TestIsScanRunning_WhenScanDone_ShouldReturnFalse(t *testing.T) { scansMockWrapper := &mock.ScansMockWrapper{Running: false} scanRunning, _ := isScanRunningOrQueued(scansMockWrapper, "ScanNotRunning") diff --git a/test/integration/pr_test.go b/test/integration/pr_test.go index 8a18aae21..88a64bb18 100644 --- a/test/integration/pr_test.go +++ b/test/integration/pr_test.go @@ -3,6 +3,7 @@ package integration import ( + "github.com/checkmarx/ast-cli/internal/wrappers" "os" "strings" "testing" @@ -10,6 +11,7 @@ import ( "github.com/checkmarx/ast-cli/internal/commands/util" "github.com/checkmarx/ast-cli/internal/logger" + "github.com/bouk/monkey" "github.com/checkmarx/ast-cli/internal/params" "gotest.tools/assert" ) @@ -26,6 +28,9 @@ const ( prGitlabIid = "PR_GITLAB_IID" prdDecorationForbiddenMessage = "A PR couldn't be created for this scan because it is still in progress." failedGettingScanError = "Failed showing a scan" + githubPRCommentCreated = "github PR comment created successfully." + gitlabPRCommentCreated = "gitlab PR comment created successfully." + outputFileName = "test_output.log" ) func TestPRGithubDecorationSuccessCase(t *testing.T) { @@ -51,6 +56,46 @@ func TestPRGithubDecorationSuccessCase(t *testing.T) { assert.NilError(t, err, "Error should be nil") } +func TestPRGithubOnPremDecorationSuccessCase(t *testing.T) { + scanID, _ := getRootScan(t, params.SastType) + args := []string{ + "utils", + "pr", + "github", + flag(params.ScanIDFlag), + scanID, + flag(params.SCMTokenFlag), + os.Getenv(prGithubToken), + flag(params.NamespaceFlag), + os.Getenv(prGithubNamespace), + flag(params.PRNumberFlag), + os.Getenv(prGithubNumber), + flag(params.RepoNameFlag), + os.Getenv(prGithubRepoName), + flag(params.CodeRepositoryFlag), + "https://github.example.com", + } + + monkey.Patch((*wrappers.PRHTTPWrapper).PostPRDecoration, func(*wrappers.PRHTTPWrapper, *wrappers.PRModel) (string, *wrappers.WebError, error) { + return githubPRCommentCreated, nil, nil + }) + defer monkey.Unpatch(wrappers.PRWrapper.PostPRDecoration) + + file := createOutputFile(t, outputFileName) + defer deleteOutputFile(t, file) + defer logger.SetOutput(os.Stdout) + + err, _ := executeCommand(t, args...) + assert.NilError(t, err, "Error should be nil") + + stdoutString, err := util.ReadFileAsString(file.Name()) + if err != nil { + t.Fatalf("Failed to read log file: %v", err) + } + + assert.Equal(t, strings.Contains(stdoutString, githubPRCommentCreated), true, "Expected output: %s", githubPRCommentCreated) +} + func TestPRGithubDecorationFailure(t *testing.T) { args := []string{ "utils", @@ -95,6 +140,49 @@ func TestPRGitlabDecorationSuccessCase(t *testing.T) { assert.NilError(t, err, "Error should be nil") } +func TestPRGitlabOnPremDecorationSuccessCase(t *testing.T) { + scanID, _ := getRootScan(t, params.SastType) + + args := []string{ + "utils", + "pr", + "gitlab", + flag(params.ScanIDFlag), + scanID, + flag(params.SCMTokenFlag), + os.Getenv(prGitlabToken), + flag(params.NamespaceFlag), + os.Getenv(prGitlabNamespace), + flag(params.RepoNameFlag), + os.Getenv(prGitlabRepoName), + flag(params.PRGitlabProjectFlag), + os.Getenv(prGitlabProjectId), + flag(params.PRIidFlag), + os.Getenv(prGitlabIid), + flag(params.CodeRepositoryFlag), + "https://gitlab.example.com", + } + + monkey.Patch((*wrappers.PRHTTPWrapper).PostPRDecoration, func(*wrappers.PRHTTPWrapper, *wrappers.GitlabPRModel) (string, *wrappers.WebError, error) { + return gitlabPRCommentCreated, nil, nil + }) + defer monkey.Unpatch(wrappers.PRWrapper.PostPRDecoration) + + file := createOutputFile(t, outputFileName) + defer deleteOutputFile(t, file) + defer logger.SetOutput(os.Stdout) + + err, _ := executeCommand(t, args...) + assert.NilError(t, err, "Error should be nil") + + stdoutString, err := util.ReadFileAsString(file.Name()) + if err != nil { + t.Fatalf("Failed to read log file: %v", err) + } + + assert.Equal(t, strings.Contains(stdoutString, gitlabPRCommentCreated), true, "Expected output: %s", gitlabPRCommentCreated) +} + func TestPRGitlabDecorationFailure(t *testing.T) { args := []string{ @@ -137,7 +225,7 @@ func TestPRGithubDecoration_WhenScanIsRunning_ShouldAvoidPRDecorationCommand(t * "--debug", } - file := createOutputFile(t, "test_output.log") + file := createOutputFile(t, outputFileName) _, _ = executeCommand(t, args...) stdoutString, err := util.ReadFileAsString(file.Name()) if err != nil { @@ -169,7 +257,7 @@ func TestPRGitlabDecoration_WhenScanIsRunning_ShouldAvoidPRDecorationCommand(t * os.Getenv(prGitlabIid), } - file := createOutputFile(t, "test_output.log") + file := createOutputFile(t, outputFileName) _, _ = executeCommand(t, args...) stdoutString, err := util.ReadFileAsString(file.Name()) if err != nil { From a8713186835015b3fa54381ebb6c11fdee077848 Mon Sep 17 00:00:00 2001 From: miryamfoiferCX Date: Thu, 31 Oct 2024 15:10:56 +0200 Subject: [PATCH 05/16] update go.sum file --- go.sum | 3 +++ 1 file changed, 3 insertions(+) diff --git a/go.sum b/go.sum index 5e024f0a4..4e1b39b18 100644 --- a/go.sum +++ b/go.sum @@ -157,6 +157,9 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/bouk/monkey v1.0.0 h1:k6z8fLlPhETfn5l9rlWVE7Q6B23DoaqosTdArvNQRdc= +github.com/bouk/monkey v1.0.0/go.mod h1:PG/63f4XEUlVyW1ttIeOJmJhhe1+t9EC/je3eTjvFhE= +github.com/bouk/monkey v1.0.2/go.mod h1:OqickVX3tNx6t33n1xvtTtu85YN5s6cKwVug+oHMaIA= github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= From fbe5f4727c0130e3b199ee519865b4458ceb5894 Mon Sep 17 00:00:00 2001 From: miryamfoiferCX Date: Sun, 3 Nov 2024 09:35:39 +0200 Subject: [PATCH 06/16] fix Unpatch command --- test/integration/pr_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/pr_test.go b/test/integration/pr_test.go index 88a64bb18..e47b8fbb4 100644 --- a/test/integration/pr_test.go +++ b/test/integration/pr_test.go @@ -79,7 +79,7 @@ func TestPRGithubOnPremDecorationSuccessCase(t *testing.T) { monkey.Patch((*wrappers.PRHTTPWrapper).PostPRDecoration, func(*wrappers.PRHTTPWrapper, *wrappers.PRModel) (string, *wrappers.WebError, error) { return githubPRCommentCreated, nil, nil }) - defer monkey.Unpatch(wrappers.PRWrapper.PostPRDecoration) + defer monkey.Unpatch((*wrappers.PRHTTPWrapper).PostPRDecoration) file := createOutputFile(t, outputFileName) defer deleteOutputFile(t, file) @@ -166,7 +166,7 @@ func TestPRGitlabOnPremDecorationSuccessCase(t *testing.T) { monkey.Patch((*wrappers.PRHTTPWrapper).PostPRDecoration, func(*wrappers.PRHTTPWrapper, *wrappers.GitlabPRModel) (string, *wrappers.WebError, error) { return gitlabPRCommentCreated, nil, nil }) - defer monkey.Unpatch(wrappers.PRWrapper.PostPRDecoration) + defer monkey.Unpatch((*wrappers.PRHTTPWrapper).PostPRDecoration) file := createOutputFile(t, outputFileName) defer deleteOutputFile(t, file) From 77dca931e7a4f2e7c6fb3bad182aeeb15f3d3826 Mon Sep 17 00:00:00 2001 From: miryamfoiferCX Date: Sun, 3 Nov 2024 10:32:28 +0200 Subject: [PATCH 07/16] fix gitlab test --- test/integration/pr_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/pr_test.go b/test/integration/pr_test.go index e47b8fbb4..2c3a1dd31 100644 --- a/test/integration/pr_test.go +++ b/test/integration/pr_test.go @@ -163,10 +163,10 @@ func TestPRGitlabOnPremDecorationSuccessCase(t *testing.T) { "https://gitlab.example.com", } - monkey.Patch((*wrappers.PRHTTPWrapper).PostPRDecoration, func(*wrappers.PRHTTPWrapper, *wrappers.GitlabPRModel) (string, *wrappers.WebError, error) { + monkey.Patch((*wrappers.PRHTTPWrapper).PostGitlabPRDecoration, func(*wrappers.PRHTTPWrapper, *wrappers.GitlabPRModel) (string, *wrappers.WebError, error) { return gitlabPRCommentCreated, nil, nil }) - defer monkey.Unpatch((*wrappers.PRHTTPWrapper).PostPRDecoration) + defer monkey.Unpatch((*wrappers.PRHTTPWrapper).PostGitlabPRDecoration) file := createOutputFile(t, outputFileName) defer deleteOutputFile(t, file) From 4ea3e7f1031a57f4a4bea5e37d06f9a2b93e6655 Mon Sep 17 00:00:00 2001 From: miryamfoiferCX Date: Sun, 3 Nov 2024 12:07:19 +0200 Subject: [PATCH 08/16] print gitlab output --- test/integration/pr_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/integration/pr_test.go b/test/integration/pr_test.go index 2c3a1dd31..937b404e2 100644 --- a/test/integration/pr_test.go +++ b/test/integration/pr_test.go @@ -180,7 +180,8 @@ func TestPRGitlabOnPremDecorationSuccessCase(t *testing.T) { t.Fatalf("Failed to read log file: %v", err) } - assert.Equal(t, strings.Contains(stdoutString, gitlabPRCommentCreated), true, "Expected output: %s", gitlabPRCommentCreated) + assert.Equal(t, strings.Contains(stdoutString, gitlabPRCommentCreated), true, "Expected output: %s", gitlabPRCommentCreated, " | actual: ", stdoutString) + } func TestPRGitlabDecorationFailure(t *testing.T) { From 735f1988aaeb20d05d8bea925207ac952aa4717f Mon Sep 17 00:00:00 2001 From: miryamfoiferCX Date: Sun, 3 Nov 2024 21:54:03 +0200 Subject: [PATCH 09/16] add getCompletedScanID logic --- internal/commands/util/pr.go | 6 +++--- internal/commands/util/pr_test.go | 4 ++-- test/integration/pr_test.go | 35 ++++++++++++++++++++++--------- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/internal/commands/util/pr.go b/internal/commands/util/pr.go index f141d3632..ab5207d0d 100644 --- a/internal/commands/util/pr.go +++ b/internal/commands/util/pr.go @@ -48,7 +48,7 @@ func NewPRDecorationCommand(prWrapper wrappers.PRWrapper, policyWrapper wrappers return cmd } -func isScanRunningOrQueued(scansWrapper wrappers.ScansWrapper, scanID string) (bool, error) { +func IsScanRunningOrQueued(scansWrapper wrappers.ScansWrapper, scanID string) (bool, error) { var scanResponseModel *wrappers.ScanResponseModel var errorModel *wrappers.ErrorModel var err error @@ -168,7 +168,7 @@ func runPRDecoration(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Policy prNumberFlag, _ := cmd.Flags().GetInt(params.PRNumberFlag) apiURL, _ := cmd.Flags().GetString(params.CodeRepositoryFlag) - scanRunningOrQueued, err := isScanRunningOrQueued(scansWrapper, scanID) + scanRunningOrQueued, err := IsScanRunningOrQueued(scansWrapper, scanID) if err != nil { return err @@ -236,7 +236,7 @@ func runPRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers. gitlabProjectIDFlag, _ := cmd.Flags().GetInt(params.PRGitlabProjectFlag) apiURL, _ := cmd.Flags().GetString(params.CodeRepositoryFlag) - scanRunningOrQueued, err := isScanRunningOrQueued(scansWrapper, scanID) + scanRunningOrQueued, err := IsScanRunningOrQueued(scansWrapper, scanID) if err != nil { return err diff --git a/internal/commands/util/pr_test.go b/internal/commands/util/pr_test.go index 5d02a240d..9e11b8385 100644 --- a/internal/commands/util/pr_test.go +++ b/internal/commands/util/pr_test.go @@ -27,14 +27,14 @@ func TestNewMRDecorationCommandMustExist(t *testing.T) { func TestIsScanRunning_WhenScanRunning_ShouldReturnTrue(t *testing.T) { scansMockWrapper := &mock.ScansMockWrapper{Running: true} - scanRunning, _ := isScanRunningOrQueued(scansMockWrapper, "ScanRunning") + scanRunning, _ := IsScanRunningOrQueued(scansMockWrapper, "ScanRunning") asserts.True(t, scanRunning) } func TestIsScanRunning_WhenScanDone_ShouldReturnFalse(t *testing.T) { scansMockWrapper := &mock.ScansMockWrapper{Running: false} - scanRunning, _ := isScanRunningOrQueued(scansMockWrapper, "ScanNotRunning") + scanRunning, _ := IsScanRunningOrQueued(scansMockWrapper, "ScanNotRunning") asserts.False(t, scanRunning) } diff --git a/test/integration/pr_test.go b/test/integration/pr_test.go index 937b404e2..e22a30d53 100644 --- a/test/integration/pr_test.go +++ b/test/integration/pr_test.go @@ -3,6 +3,7 @@ package integration import ( + "fmt" "github.com/checkmarx/ast-cli/internal/wrappers" "os" "strings" @@ -31,16 +32,35 @@ const ( githubPRCommentCreated = "github PR comment created successfully." gitlabPRCommentCreated = "gitlab PR comment created successfully." outputFileName = "test_output.log" + scans = "api/scans" ) +var completedScanId = "" + +func getCompletedScanID(t *testing.T) string { + if completedScanId != "" { + return completedScanId + } + scanWrapper := wrappers.NewHTTPScansWrapper(scans) + scanID, _ := getRootScan(t, params.IacType) + + for isRunning, err := util.IsScanRunningOrQueued(scanWrapper, scanID); isRunning; isRunning, err = util.IsScanRunningOrQueued(scanWrapper, scanID) { + if err != nil { + t.Fatalf("Failed to get scan status: %v", err) + } + logger.PrintIfVerbose("Waiting for scan to finish. scan running: " + fmt.Sprintf("%t", isRunning)) + } + completedScanId = scanID + return scanID +} + func TestPRGithubDecorationSuccessCase(t *testing.T) { - scanID, _ := getRootScan(t, params.SastType) args := []string{ "utils", "pr", "github", flag(params.ScanIDFlag), - scanID, + getCompletedScanID(t), flag(params.SCMTokenFlag), os.Getenv(prGithubToken), flag(params.NamespaceFlag), @@ -57,13 +77,12 @@ func TestPRGithubDecorationSuccessCase(t *testing.T) { } func TestPRGithubOnPremDecorationSuccessCase(t *testing.T) { - scanID, _ := getRootScan(t, params.SastType) args := []string{ "utils", "pr", "github", flag(params.ScanIDFlag), - scanID, + getCompletedScanID(t), flag(params.SCMTokenFlag), os.Getenv(prGithubToken), flag(params.NamespaceFlag), @@ -117,14 +136,12 @@ func TestPRGithubDecorationFailure(t *testing.T) { } func TestPRGitlabDecorationSuccessCase(t *testing.T) { - scanID, _ := getRootScan(t, params.SastType) - args := []string{ "utils", "pr", "gitlab", flag(params.ScanIDFlag), - scanID, + getCompletedScanID(t), flag(params.SCMTokenFlag), os.Getenv(prGitlabToken), flag(params.NamespaceFlag), @@ -141,14 +158,12 @@ func TestPRGitlabDecorationSuccessCase(t *testing.T) { } func TestPRGitlabOnPremDecorationSuccessCase(t *testing.T) { - scanID, _ := getRootScan(t, params.SastType) - args := []string{ "utils", "pr", "gitlab", flag(params.ScanIDFlag), - scanID, + getCompletedScanID(t), flag(params.SCMTokenFlag), os.Getenv(prGitlabToken), flag(params.NamespaceFlag), From 6a6d338a40b0d4b04eff1b561e754ee91534f68b Mon Sep 17 00:00:00 2001 From: miryamfoiferCX Date: Sun, 3 Nov 2024 22:13:46 +0200 Subject: [PATCH 10/16] CR fixes --- internal/params/flags.go | 2 +- test/integration/pr_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/params/flags.go b/internal/params/flags.go index 76007460a..b52903aee 100644 --- a/internal/params/flags.go +++ b/internal/params/flags.go @@ -34,7 +34,7 @@ const ( BranchFlagSh = "b" ScanIDFlag = "scan-id" CodeRepositoryFlag = "code-repository-url" - CodeRepositoryFlagUsage = "Code repository URL (optional for self-hosted Azure DevOps)" + CodeRepositoryFlagUsage = "Code repository URL (optional for self-hosted SCMs)" BranchFlagUsage = "Branch to scan" MainBranchFlag = "branch" ScaResolverFlag = "sca-resolver" diff --git a/test/integration/pr_test.go b/test/integration/pr_test.go index e22a30d53..2fa4cbb0c 100644 --- a/test/integration/pr_test.go +++ b/test/integration/pr_test.go @@ -76,7 +76,7 @@ func TestPRGithubDecorationSuccessCase(t *testing.T) { assert.NilError(t, err, "Error should be nil") } -func TestPRGithubOnPremDecorationSuccessCase(t *testing.T) { +func TestPRGithubDecoration_WhenUseCodeRepositoryFlag_ShouldSuccess(t *testing.T) { args := []string{ "utils", "pr", @@ -157,7 +157,7 @@ func TestPRGitlabDecorationSuccessCase(t *testing.T) { assert.NilError(t, err, "Error should be nil") } -func TestPRGitlabOnPremDecorationSuccessCase(t *testing.T) { +func TestPRGitlabDecoration_WhenUseCodeRepositoryFlag_ShouldSuccess(t *testing.T) { args := []string{ "utils", "pr", From dd0cbd898eaae77146ae0337d3ece903b64ecb55 Mon Sep 17 00:00:00 2001 From: miryamfoiferCX Date: Sun, 3 Nov 2024 22:22:26 +0200 Subject: [PATCH 11/16] fix SCA vulnerability --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 62374c859..5791c6c11 100644 --- a/go.mod +++ b/go.mod @@ -262,7 +262,7 @@ require ( gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - helm.sh/helm/v3 v3.15.4 // indirect + helm.sh/helm/v3 v3.16.2 // indirect k8s.io/api v0.30.3 // indirect k8s.io/apiextensions-apiserver v0.30.3 // indirect k8s.io/apimachinery v0.30.3 // indirect From 122fcc3b92264df19ac8f946ff71b6d51f414f89 Mon Sep 17 00:00:00 2001 From: miryamfoiferCX Date: Sun, 3 Nov 2024 22:55:04 +0200 Subject: [PATCH 12/16] revert fix for SCA --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 5791c6c11..62374c859 100644 --- a/go.mod +++ b/go.mod @@ -262,7 +262,7 @@ require ( gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - helm.sh/helm/v3 v3.16.2 // indirect + helm.sh/helm/v3 v3.15.4 // indirect k8s.io/api v0.30.3 // indirect k8s.io/apiextensions-apiserver v0.30.3 // indirect k8s.io/apimachinery v0.30.3 // indirect From f0b657c7fe5e1a2797b2205e562f31114a48bb83 Mon Sep 17 00:00:00 2001 From: miryamfoiferCX Date: Mon, 4 Nov 2024 11:15:32 +0200 Subject: [PATCH 13/16] init scan at TestMain logic --- test/integration/root_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/root_test.go b/test/integration/root_test.go index e5346ade7..e7d3ad0b1 100644 --- a/test/integration/root_test.go +++ b/test/integration/root_test.go @@ -47,6 +47,7 @@ var rootProjectName string func TestMain(m *testing.M) { log.Println("CLI integration tests started") viper.SetDefault(resolverEnvVar, resolverEnvVarDefault) + getRootScan(testInstance, commonParams.IacType) exitVal := m.Run() //deleteScanAndProject() log.Println("CLI integration tests done") From 24b16db6aee918467316544607e50d675812ba6b Mon Sep 17 00:00:00 2001 From: miryamfoiferCX Date: Mon, 4 Nov 2024 11:47:37 +0200 Subject: [PATCH 14/16] revert init rootScan, clean logs, and use local parameter in first PRDecoration test --- test/integration/pr_test.go | 7 ++++++- test/integration/root_test.go | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/test/integration/pr_test.go b/test/integration/pr_test.go index 2fa4cbb0c..8e8429aac 100644 --- a/test/integration/pr_test.go +++ b/test/integration/pr_test.go @@ -44,6 +44,10 @@ func getCompletedScanID(t *testing.T) string { scanWrapper := wrappers.NewHTTPScansWrapper(scans) scanID, _ := getRootScan(t, params.IacType) + file := createOutputFile(t, outputFileName) + defer deleteOutputFile(t, file) + defer logger.SetOutput(os.Stdout) + for isRunning, err := util.IsScanRunningOrQueued(scanWrapper, scanID); isRunning; isRunning, err = util.IsScanRunningOrQueued(scanWrapper, scanID) { if err != nil { t.Fatalf("Failed to get scan status: %v", err) @@ -55,12 +59,13 @@ func getCompletedScanID(t *testing.T) string { } func TestPRGithubDecorationSuccessCase(t *testing.T) { + scanID := getCompletedScanID(t) args := []string{ "utils", "pr", "github", flag(params.ScanIDFlag), - getCompletedScanID(t), + scanID, flag(params.SCMTokenFlag), os.Getenv(prGithubToken), flag(params.NamespaceFlag), diff --git a/test/integration/root_test.go b/test/integration/root_test.go index e7d3ad0b1..e5346ade7 100644 --- a/test/integration/root_test.go +++ b/test/integration/root_test.go @@ -47,7 +47,6 @@ var rootProjectName string func TestMain(m *testing.M) { log.Println("CLI integration tests started") viper.SetDefault(resolverEnvVar, resolverEnvVarDefault) - getRootScan(testInstance, commonParams.IacType) exitVal := m.Run() //deleteScanAndProject() log.Println("CLI integration tests done") From 9f743b01c4a59befe2b5cb4bd02ca8722d3d6894 Mon Sep 17 00:00:00 2001 From: miryamfoiferCX Date: Mon, 4 Nov 2024 15:56:07 +0200 Subject: [PATCH 15/16] revert old tests refactor --- test/integration/pr_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/integration/pr_test.go b/test/integration/pr_test.go index 8e8429aac..932273862 100644 --- a/test/integration/pr_test.go +++ b/test/integration/pr_test.go @@ -59,7 +59,7 @@ func getCompletedScanID(t *testing.T) string { } func TestPRGithubDecorationSuccessCase(t *testing.T) { - scanID := getCompletedScanID(t) + scanID, _ := getRootScan(t, params.SastType) args := []string{ "utils", "pr", @@ -141,12 +141,13 @@ func TestPRGithubDecorationFailure(t *testing.T) { } func TestPRGitlabDecorationSuccessCase(t *testing.T) { + scanID, _ := getRootScan(t, params.SastType) args := []string{ "utils", "pr", "gitlab", flag(params.ScanIDFlag), - getCompletedScanID(t), + scanID, flag(params.SCMTokenFlag), os.Getenv(prGitlabToken), flag(params.NamespaceFlag), From 0ed204cfd0bd6783ba4943daec9833b55550c8f8 Mon Sep 17 00:00:00 2001 From: miryamfoiferCX Date: Tue, 5 Nov 2024 10:28:12 +0200 Subject: [PATCH 16/16] fix for trivy --- go.mod | 2 +- go.sum | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index befb23bab..b8b30262b 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/bouk/monkey v1.0.0 github.com/checkmarxDev/gpt-wrapper v0.0.0-20230721160222-85da2fd1cc4c github.com/golang-jwt/jwt v3.2.2+incompatible - github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 + github.com/gomarkdown/markdown v0.0.0-20241102151059-6bc1ffdc6e8c github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/google/uuid v1.6.0 github.com/gookit/color v1.5.4 diff --git a/go.sum b/go.sum index 8892b0c99..767da068c 100644 --- a/go.sum +++ b/go.sum @@ -159,7 +159,6 @@ github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwN github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bouk/monkey v1.0.0 h1:k6z8fLlPhETfn5l9rlWVE7Q6B23DoaqosTdArvNQRdc= github.com/bouk/monkey v1.0.0/go.mod h1:PG/63f4XEUlVyW1ttIeOJmJhhe1+t9EC/je3eTjvFhE= -github.com/bouk/monkey v1.0.2/go.mod h1:OqickVX3tNx6t33n1xvtTtu85YN5s6cKwVug+oHMaIA= github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= @@ -432,8 +431,8 @@ github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 h1:EcQR3gusLHN46TAD+G+EbaaqJArt5vHhNpXAa12PQf4= -github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= +github.com/gomarkdown/markdown v0.0.0-20241102151059-6bc1ffdc6e8c h1:CrUrhyZMx1Me0fyvvFtQq6W18ss2WEfgPRfjnwrTtiQ= +github.com/gomarkdown/markdown v0.0.0-20241102151059-6bc1ffdc6e8c/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=