Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Code Repository Flag & Support PR Decoration For GH/GL On-prem (AST-72979, AST-72975) #921

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pr-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
OrShamirCM marked this conversation as resolved.
Show resolved Hide resolved
echo "::error::PR title must contain a Jira ticket ID at the end in the format '(AST-XXXX)'."
exit 1
fi
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM cgr.dev/chainguard/bash@sha256:f8e48690d991e6814c81f063833176439e8f0d4bc1c5f0a47f94858dea3e4f44
FROM cgr.dev/chainguard/bash@sha256:e1d16dec8d976859080d984167109b3557c2b6494f10be08147806b78bdef691
USER nonroot
OrShamirCM marked this conversation as resolved.
Show resolved Hide resolved

COPY cx /app/bin/cx
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ require (
github.com/Checkmarx/gen-ai-prompts v0.0.0-20240807143411-708ceec12b63
github.com/CheckmarxDev/containers-resolver v1.0.14
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
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
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ 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/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=
Expand Down Expand Up @@ -429,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=
Expand Down
36 changes: 32 additions & 4 deletions internal/commands/util/pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -44,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
Expand Down Expand Up @@ -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"))
Expand Down Expand Up @@ -120,7 +125,7 @@ func PRDecorationGitlab(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Pol
Example: heredoc.Doc(
`
$ cx utils pr gitlab --scan-id <scan-id> --token <PAT> --namespace <organization> --repo-name <repository>
--iid <pr iid> --gitlab-project <gitlab project ID>
--iid <pr iid> --gitlab-project <gitlab project ID> --code-repository-url <code-repository-url>
`,
),
Annotations: map[string]string{
Expand All @@ -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"))
Expand Down Expand Up @@ -160,8 +166,9 @@ 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)
scanRunningOrQueued, err := IsScanRunningOrQueued(scansWrapper, scanID)

if err != nil {
return err
Expand All @@ -179,13 +186,16 @@ func runPRDecoration(prWrapper wrappers.PRWrapper, policyWrapper wrappers.Policy
}

// Build and post the pr decoration
updatedAPIURL := updateAPIURLForGithubOnPrem(apiURL)

prModel := &wrappers.PRModel{
ScanID: scanID,
ScmToken: scmTokenFlag,
Namespace: namespaceFlag,
RepoName: repoNameFlag,
PrNumber: prNumberFlag,
Policies: policies,
APIURL: updatedAPIURL,
}
prResponse, errorModel, err := prWrapper.PostPRDecoration(prModel)
if err != nil {
Expand All @@ -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)
Expand All @@ -210,8 +234,9 @@ 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)
scanRunningOrQueued, err := IsScanRunningOrQueued(scansWrapper, scanID)

if err != nil {
return err
Expand All @@ -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,
Expand All @@ -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)
Expand Down
30 changes: 26 additions & 4 deletions internal/commands/util/pr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ 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")
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")
scanRunning, _ := IsScanRunningOrQueued(scansMockWrapper, "ScanNotRunning")
asserts.False(t, scanRunning)
}

Expand All @@ -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)
}
2 changes: 2 additions & 0 deletions internal/params/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ const (
BranchFlag = "branch"
BranchFlagSh = "b"
ScanIDFlag = "scan-id"
CodeRepositoryFlag = "code-repository-url"
OrShamirCM marked this conversation as resolved.
Show resolved Hide resolved
CodeRepositoryFlagUsage = "Code repository URL (optional for self-hosted SCMs)"
BranchFlagUsage = "Branch to scan"
MainBranchFlag = "branch"
ScaResolverFlag = "sca-resolver"
Expand Down
2 changes: 2 additions & 0 deletions internal/wrappers/pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
Loading
Loading