From fe02cbdac36c82b0591489b36b31525157ad2933 Mon Sep 17 00:00:00 2001 From: attiasas Date: Thu, 23 Jul 2026 18:02:46 +0300 Subject: [PATCH 1/6] Add support to get UI route for git scan results --- audit_test.go | 2 +- commands/audit/audit.go | 53 ++++++++++++++++++-------- commands/audit/auditparams.go | 8 ++++ go.mod | 3 +- go.sum | 4 +- utils/results/output/reportartifact.go | 5 +-- utils/xray/artifact/artifactstatus.go | 19 +++++++-- utils/xsc/scanresultsuiroute.go | 47 +++++++++++++++++++++++ 8 files changed, 116 insertions(+), 25 deletions(-) create mode 100644 utils/xsc/scanresultsuiroute.go diff --git a/audit_test.go b/audit_test.go index 4ef9420e5..5b7683372 100644 --- a/audit_test.go +++ b/audit_test.go @@ -1035,7 +1035,7 @@ func TestAuditNewScaSimpleJsonMultipleWorkingDirs(t *testing.T) { ) assert.NoError(t, err) validations.VerifySimpleJsonResults(t, output, validations.ValidationParams{ - Total: &validations.TotalCount{Vulnerabilities: 11}, + Total: &validations.TotalCount{Vulnerabilities: 11}, Vulnerabilities: &validations.VulnerabilityCount{ ValidateScan: &validations.ScanCount{Sca: 8, Sast: 2, Secrets: 1}, }, diff --git a/commands/audit/audit.go b/commands/audit/audit.go index 10ab5fae2..03b1f5e81 100644 --- a/commands/audit/audit.go +++ b/commands/audit/audit.go @@ -31,6 +31,7 @@ import ( "github.com/jfrog/jfrog-cli-security/utils/results" "github.com/jfrog/jfrog-cli-security/utils/results/output" "github.com/jfrog/jfrog-cli-security/utils/techutils" + "github.com/jfrog/jfrog-cli-security/utils/xray/artifact" "golang.org/x/exp/slices" @@ -984,50 +985,72 @@ func processScanResults(params *AuditParams, cmdResults *results.SecurityCommand uploadPath := "" if params.uploadCdxResults { log.Debug("Finished scanning. Uploading scan results to Artifactory") - if params.rtResultRepository == "" { + if params.GetRtResultRepositoryWithProjectKey() == "" { return cmdResults.AddGeneralError(errors.New("results repository was not provided, can't upload scan results to Artifactory"), false) } - rtResultRepository := params.rtResultRepository - if params.resultsContext.ProjectKey != "" { - rtResultRepository = fmt.Sprintf("%s-%s", params.resultsContext.ProjectKey, rtResultRepository) - } if params.Progress() != nil { params.Progress().SetHeadlineMsg("Uploading scan results to platform") } - uploadPath, err = uploadCdxResults(params, cmdResults, rtResultRepository) + uploadPath, err = uploadCdxResults(params, cmdResults) if err != nil { return cmdResults.AddGeneralError(fmt.Errorf("failed to upload scan results to Artifactory: %s", err.Error()), false) } + if uiRoute, err := getScanResultsUiRoute(params, uploadPath); err != nil { + log.Warn(fmt.Sprintf("failed to get scan results UI route: %s", err.Error())) + } else if uiRoute != "" { + cmdResults.SetResultsPlatformUrl(uiRoute) + } } // Violations fetching if cmdResults.HasViolationContext() { if params.Progress() != nil { params.Progress().SetHeadlineMsg("Fetching violations") } - rtResultRepository := params.rtResultRepository - if rtResultRepository != "" && params.resultsContext.ProjectKey != "" { - rtResultRepository = fmt.Sprintf("%s-%s", params.resultsContext.ProjectKey, rtResultRepository) - } - if err = fetchViolations(uploadPath, cmdResults, params, rtResultRepository); err != nil { + if err = fetchViolations(uploadPath, cmdResults, params); err != nil { cmdResults.AddGeneralError(fmt.Errorf("failed to get violations: %s", err.Error()), cmdResults.AllowPartialResults) } } return cmdResults } -func uploadCdxResults(auditParams *AuditParams, cmdResults *results.SecurityCommandResults, rtResultRepository string) (uploadPath string, err error) { +func uploadCdxResults(auditParams *AuditParams, cmdResults *results.SecurityCommandResults) (uploadPath string, err error) { serverDetails, err := auditParams.ServerDetails() if err != nil { err = fmt.Errorf("failed to get server details: %s", err.Error()) return } - if uploadPath, err = output.UploadCommandResults(serverDetails, rtResultRepository, cmdResults); err != nil { + if uploadPath, err = output.UploadCommandResults(serverDetails, auditParams.GetRtResultRepositoryWithProjectKey(), cmdResults); err != nil { err = fmt.Errorf("failed to upload scan results to Artifactory: %s", err.Error()) } return } -func fetchViolations(uploadPath string, cmdResults *results.SecurityCommandResults, auditParams *AuditParams, rtResultRepository string) (err error) { +func getScanResultsUiRoute(auditParams *AuditParams, uploadPath string) (string, error) { + if auditParams.GitContext() == nil { + return "", nil + } + serverDetails, err := auditParams.ServerDetails() + if err != nil { + return "", fmt.Errorf("failed to get server details: %s", err.Error()) + } + xrayManager, err := xrayutils.CreateXrayServiceManager(serverDetails, xrayutils.WithScopedProjectKey(auditParams.resultsContext.ProjectKey)) + if err != nil { + return "", fmt.Errorf("failed to create Xray service manager: %s", err.Error()) + } + // first in path is the repository (delimiter '/') rest is the path + if err = artifact.WaitForArtifactScanStatus(xrayManager, strings.Split(uploadPath, "/")[0], strings.Join(strings.Split(uploadPath, "/")[1:], "/"), artifact.ScanStarted()); err != nil { + return "", fmt.Errorf("failed to wait for artifact scan status: %s", err.Error()) + } + return xsc.GetScanResultsUiRoute(&xsc.ScanResultsUiRouteParams{ + XrayVersion: auditParams.GetXrayVersion(), + ServerDetails: serverDetails, + ProjectKey: auditParams.resultsContext.ProjectKey, + GitContext: auditParams.GitContext(), + ScanResultArtifactPath: uploadPath, + }) +} + +func fetchViolations(uploadPath string, cmdResults *results.SecurityCommandResults, auditParams *AuditParams) (err error) { serverDetails, err := auditParams.ServerDetails() if err != nil { return fmt.Errorf("failed to get server details: %s", err.Error()) @@ -1036,7 +1059,7 @@ func fetchViolations(uploadPath string, cmdResults *results.SecurityCommandResul local.WithAllowedLicenses(auditParams.allowedLicenses), enforcer.WithServerDetails(serverDetails), enforcer.WithProjectKey(auditParams.resultsContext.ProjectKey), - enforcer.WithArtifactParams(rtResultRepository, uploadPath), + enforcer.WithArtifactParams(auditParams.GetRtResultRepositoryWithProjectKey(), uploadPath), enforcer.WithWatches(auditParams.resultsContext.Watches), enforcer.WithResultsOutputDir(auditParams.scanResultsOutputDir), ) diff --git a/commands/audit/auditparams.go b/commands/audit/auditparams.go index 99b7a18aa..5cd8a8c73 100644 --- a/commands/audit/auditparams.go +++ b/commands/audit/auditparams.go @@ -1,6 +1,7 @@ package audit import ( + "fmt" "time" jfrogappsconfig "github.com/jfrog/jfrog-apps-config/go" @@ -361,3 +362,10 @@ func (params *AuditParams) SetIncludeSbom(include bool) *AuditParams { params.resultsContext.IncludeSbom = include return params } + +func (params *AuditParams) GetRtResultRepositoryWithProjectKey() string { + if params.rtResultRepository != "" && params.resultsContext.ProjectKey != "" { + return fmt.Sprintf("%s-%s", params.resultsContext.ProjectKey, params.rtResultRepository) + } + return params.rtResultRepository +} diff --git a/go.mod b/go.mod index 729e44ccb..0044a2112 100644 --- a/go.mod +++ b/go.mod @@ -157,7 +157,8 @@ require ( gopkg.in/warnings.v0 v0.1.2 // indirect ) -// replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go master +// attiasas:feature/XRAY-132336-add-git-route-api +replace github.com/jfrog/jfrog-client-go => github.com/attiasas/jfrog-client-go v0.0.0-20260723135908-416123e5b716 // replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 master diff --git a/go.sum b/go.sum index d5a792c9d..080c6e50a 100644 --- a/go.sum +++ b/go.sum @@ -21,6 +21,8 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/attiasas/jfrog-client-go v0.0.0-20260723135908-416123e5b716 h1:KodzfX78U5pAnf74QXbdMJGBgjo7ip4pxkqSJo7p0+c= +github.com/attiasas/jfrog-client-go v0.0.0-20260723135908-416123e5b716/go.mod h1:FHpjN1nTDoj96xd6obe27EOgGErqzU0rQgC96L3Ch9E= github.com/beevik/etree v1.6.0 h1:u8Kwy8pp9D9XeITj2Z0XtA5qqZEmtJtuXZRQi+j03eE= github.com/beevik/etree v1.6.0/go.mod h1:bh4zJxiIr62SOf9pRzN7UUYaEDa9HEKafK25+sLc0Gc= github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= @@ -173,8 +175,6 @@ github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260714082320-4fd5a71b4b4a h1:d github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260714082320-4fd5a71b4b4a/go.mod h1:BJ8x7NhWxJvhG5Bjca2GwWlZN2bxlo+8AnpuRnZ9RMM= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260624085155-5ba797de2616 h1:bioFXGzf3pF2qnC3LZD1S1saWiHSekL4vdsDSWksj/4= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260624085155-5ba797de2616/go.mod h1:9R90mhbczGXwW5EGlDs7F08ejQU/xdoDhYHMvzBiqgE= -github.com/jfrog/jfrog-client-go v1.55.1-0.20260624085832-de0c68a23c43 h1:akoiWauP27YxVXcRkCC8ahgDLxqiARUAVEB+KUPO2OE= -github.com/jfrog/jfrog-client-go v1.55.1-0.20260624085832-de0c68a23c43/go.mod h1:FHpjN1nTDoj96xd6obe27EOgGErqzU0rQgC96L3Ch9E= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/kevinburke/ssh_config v1.6.0 h1:J1FBfmuVosPHf5GRdltRLhPJtJpTlMdKTBjRgTaQBFY= diff --git a/utils/results/output/reportartifact.go b/utils/results/output/reportartifact.go index e5a499f16..471c37f24 100644 --- a/utils/results/output/reportartifact.go +++ b/utils/results/output/reportartifact.go @@ -49,12 +49,11 @@ func UploadCommandResults(serverDetails *config.ServerDetails, rtResultRepositor } func GetCommandResultsPlatformUrlMessage(cmdResults *results.SecurityCommandResults, pretty bool) string { - isGitContext := cmdResults.CmdType == utils.SourceCode && cmdResults.GitContext != nil - uploadMsg := upload.GetScanResultsPlatformUrlMessage(isGitContext) + uploadMsg := upload.GetScanResultsPlatformUrlMessage(cmdResults.CmdType == utils.SourceCode && cmdResults.GitContext != nil) if pretty { uploadMsg = coreutils.PrintTitle(uploadMsg) } - if isGitContext { + if cmdResults.ResultsPlatformUrl == "" { return uploadMsg } link := cmdResults.ResultsPlatformUrl diff --git a/utils/xray/artifact/artifactstatus.go b/utils/xray/artifact/artifactstatus.go index b9b084a97..1d026da30 100644 --- a/utils/xray/artifact/artifactstatus.go +++ b/utils/xray/artifact/artifactstatus.go @@ -33,8 +33,9 @@ func GetArtifactScanStatus(xrayManager *xray.XrayServicesManager, repo, path str } type ScanCompleteParams struct { - Overall bool - Steps []XrayScanStep + Overall bool + WaitForScanStarted bool + Steps []XrayScanStep } type ScanCompleteOption func(params *ScanCompleteParams) @@ -45,6 +46,12 @@ func OverallCompletion() ScanCompleteOption { } } +func ScanStarted() ScanCompleteOption { + return func(params *ScanCompleteParams) { + params.WaitForScanStarted = true + } +} + func Steps(steps ...XrayScanStep) ScanCompleteOption { return func(params *ScanCompleteParams) { params.Steps = steps @@ -94,7 +101,13 @@ func WaitForArtifactScanStatus(xrayManager *xray.XrayServicesManager, repo, path } return } - log.Debug(fmt.Sprintf("Artifact scan completed the requested steps. [%s]", strings.Join(statusMapToString(getStatusMap(status.Details, params.Steps, false)), ", "))) + if !params.Overall && len(params.Steps) == 0 { + log.Debug(fmt.Sprintf("Artifact scan started. (%s)", status.Overall.Status)) + } else if params.Overall { + log.Debug(fmt.Sprintf("Artifact scan completed. (%s)", status.Overall.Status)) + } else { + log.Debug(fmt.Sprintf("Artifact scan completed the requested steps. [%s]", strings.Join(statusMapToString(getStatusMap(status.Details, params.Steps, false)), ", "))) + } // We don't need to return any response body, as we don't use it. // We just need to stop the polling executor. shouldStop = true diff --git a/utils/xsc/scanresultsuiroute.go b/utils/xsc/scanresultsuiroute.go new file mode 100644 index 000000000..799024bbc --- /dev/null +++ b/utils/xsc/scanresultsuiroute.go @@ -0,0 +1,47 @@ +package xsc + +import ( + "fmt" + + "github.com/jfrog/jfrog-cli-core/v2/utils/config" + + xrayutils "github.com/jfrog/jfrog-cli-security/utils/xray" + clientutils "github.com/jfrog/jfrog-client-go/utils" + "github.com/jfrog/jfrog-client-go/utils/log" + xscServices "github.com/jfrog/jfrog-client-go/xsc/services" +) + +type ScanResultsUiRouteParams struct { + XrayVersion string + ServerDetails *config.ServerDetails + ProjectKey string + GitContext *xscServices.XscGitInfoContext + ScanResultArtifactPath string +} + +func GetScanResultsUiRoute(params *ScanResultsUiRouteParams) (string, error) { + if err := clientutils.ValidateMinimumVersion(clientutils.Xray, params.XrayVersion, xscServices.GetUIRouteAPIMinXrayVersion); err != nil { + log.Debug(fmt.Sprintf("Minimal Xray version required to use a configProfile is by name '%s'. All configurations will be induced from provided Env vars and files", xscServices.GetUIRouteAPIMinXrayVersion)) + return "", nil + } + if params.GitContext == nil || params.ServerDetails == nil { + log.Verbose("No git context or server details provided, skipping getting scan results UI route") + return "", nil + } + + xscService, err := CreateXscService(params.ServerDetails, xrayutils.WithScopedProjectKey(params.ProjectKey)) + if err != nil { + return "", fmt.Errorf("failed to create XSC service: %w", err) + } + + resp, err := xscService.GetScanResultsUIRoute(params.GitContext) + if err != nil { + return "", fmt.Errorf("failed to get scan results UI route: %w", err) + } + + if params.ScanResultArtifactPath != "" && resp.Path != params.ScanResultArtifactPath { + return "", fmt.Errorf("scan result artifact path '%s' does not match the expected path '%s'", params.ScanResultArtifactPath, resp.Path) + } + + return resp.Url, nil +} From a12f7fdd83e2caf652d3bc7160ac9c3641d54e70 Mon Sep 17 00:00:00 2001 From: attiasas Date: Sun, 26 Jul 2026 10:41:36 +0300 Subject: [PATCH 2/6] Fixes and update deps --- commands/audit/audit.go | 3 +-- go.mod | 2 +- go.sum | 4 ++-- utils/xray/artifact/artifactstatus.go | 8 ++++++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/commands/audit/audit.go b/commands/audit/audit.go index 03b1f5e81..53c2d95f4 100644 --- a/commands/audit/audit.go +++ b/commands/audit/audit.go @@ -1037,8 +1037,7 @@ func getScanResultsUiRoute(auditParams *AuditParams, uploadPath string) (string, if err != nil { return "", fmt.Errorf("failed to create Xray service manager: %s", err.Error()) } - // first in path is the repository (delimiter '/') rest is the path - if err = artifact.WaitForArtifactScanStatus(xrayManager, strings.Split(uploadPath, "/")[0], strings.Join(strings.Split(uploadPath, "/")[1:], "/"), artifact.ScanStarted()); err != nil { + if err = artifact.WaitForArtifactScanStatus(xrayManager, auditParams.GetRtResultRepositoryWithProjectKey(), uploadPath, artifact.ScanStarted()); err != nil { return "", fmt.Errorf("failed to wait for artifact scan status: %s", err.Error()) } return xsc.GetScanResultsUiRoute(&xsc.ScanResultsUiRouteParams{ diff --git a/go.mod b/go.mod index 0044a2112..839d2f0ee 100644 --- a/go.mod +++ b/go.mod @@ -158,7 +158,7 @@ require ( ) // attiasas:feature/XRAY-132336-add-git-route-api -replace github.com/jfrog/jfrog-client-go => github.com/attiasas/jfrog-client-go v0.0.0-20260723135908-416123e5b716 +replace github.com/jfrog/jfrog-client-go => github.com/attiasas/jfrog-client-go v0.0.0-20260726073427-df350e2cf58d // replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 master diff --git a/go.sum b/go.sum index 080c6e50a..44ffc8e0d 100644 --- a/go.sum +++ b/go.sum @@ -21,8 +21,8 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/attiasas/jfrog-client-go v0.0.0-20260723135908-416123e5b716 h1:KodzfX78U5pAnf74QXbdMJGBgjo7ip4pxkqSJo7p0+c= -github.com/attiasas/jfrog-client-go v0.0.0-20260723135908-416123e5b716/go.mod h1:FHpjN1nTDoj96xd6obe27EOgGErqzU0rQgC96L3Ch9E= +github.com/attiasas/jfrog-client-go v0.0.0-20260726073427-df350e2cf58d h1:lwiC8BP/yZycOg81OrkWpxGqnoLYMZiKSspLnyPFWcU= +github.com/attiasas/jfrog-client-go v0.0.0-20260726073427-df350e2cf58d/go.mod h1:FHpjN1nTDoj96xd6obe27EOgGErqzU0rQgC96L3Ch9E= github.com/beevik/etree v1.6.0 h1:u8Kwy8pp9D9XeITj2Z0XtA5qqZEmtJtuXZRQi+j03eE= github.com/beevik/etree v1.6.0/go.mod h1:bh4zJxiIr62SOf9pRzN7UUYaEDa9HEKafK25+sLc0Gc= github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= diff --git a/utils/xray/artifact/artifactstatus.go b/utils/xray/artifact/artifactstatus.go index 1d026da30..f8ae52b45 100644 --- a/utils/xray/artifact/artifactstatus.go +++ b/utils/xray/artifact/artifactstatus.go @@ -70,9 +70,13 @@ func NewScanCompleteParams(options ...ScanCompleteOption) *ScanCompleteParams { func WaitForArtifactScanStatus(xrayManager *xray.XrayServicesManager, repo, path string, options ...ScanCompleteOption) error { params := NewScanCompleteParams(options...) if !params.Overall && len(params.Steps) == 0 { - return fmt.Errorf("no scan completion criteria were provided") + if !params.WaitForScanStarted { + return fmt.Errorf("no scan completion criteria were provided") + } + log.Debug("Waiting for artifact scan to start.") + } else { + log.Debug(fmt.Sprintf("Waiting for artifact scan completion. Overall: %t, Steps: %v", params.Overall, params.Steps)) } - log.Debug(fmt.Sprintf("Waiting for artifact scan completion. Overall: %t, Steps: %v", params.Overall, params.Steps)) pollingExecutor := &httputils.PollingExecutor{ PollingInterval: ArtifactStatusFetchingIntervalNano, Timeout: ArtifactStatusFetchTimeoutNano, From ce030d8bb1b968ff50dfeffa35403564033bf543 Mon Sep 17 00:00:00 2001 From: attiasas Date: Mon, 27 Jul 2026 11:50:59 +0300 Subject: [PATCH 3/6] fix static issues --- utils/xray/artifact/artifactstatus.go | 7 ++++--- utils/xsc/scanresultsuiroute.go | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/utils/xray/artifact/artifactstatus.go b/utils/xray/artifact/artifactstatus.go index f8ae52b45..1010ed54d 100644 --- a/utils/xray/artifact/artifactstatus.go +++ b/utils/xray/artifact/artifactstatus.go @@ -105,11 +105,12 @@ func WaitForArtifactScanStatus(xrayManager *xray.XrayServicesManager, repo, path } return } - if !params.Overall && len(params.Steps) == 0 { + switch { + case !params.Overall && len(params.Steps) == 0: log.Debug(fmt.Sprintf("Artifact scan started. (%s)", status.Overall.Status)) - } else if params.Overall { + case params.Overall: log.Debug(fmt.Sprintf("Artifact scan completed. (%s)", status.Overall.Status)) - } else { + default: log.Debug(fmt.Sprintf("Artifact scan completed the requested steps. [%s]", strings.Join(statusMapToString(getStatusMap(status.Details, params.Steps, false)), ", "))) } // We don't need to return any response body, as we don't use it. diff --git a/utils/xsc/scanresultsuiroute.go b/utils/xsc/scanresultsuiroute.go index 799024bbc..f582babed 100644 --- a/utils/xsc/scanresultsuiroute.go +++ b/utils/xsc/scanresultsuiroute.go @@ -20,8 +20,8 @@ type ScanResultsUiRouteParams struct { } func GetScanResultsUiRoute(params *ScanResultsUiRouteParams) (string, error) { - if err := clientutils.ValidateMinimumVersion(clientutils.Xray, params.XrayVersion, xscServices.GetUIRouteAPIMinXrayVersion); err != nil { - log.Debug(fmt.Sprintf("Minimal Xray version required to use a configProfile is by name '%s'. All configurations will be induced from provided Env vars and files", xscServices.GetUIRouteAPIMinXrayVersion)) + if clientutils.ValidateMinimumVersion(clientutils.Xray, params.XrayVersion, xscServices.GetUIRouteAPIMinXrayVersion) != nil { + log.Debug(fmt.Sprintf("Minimal Xray version required for scan results UI route is '%s'. Skipping.", xscServices.GetUIRouteAPIMinXrayVersion)) return "", nil } if params.GitContext == nil || params.ServerDetails == nil { From 3356ce3c971467a4dc7d54a603814f8c3dc12929 Mon Sep 17 00:00:00 2001 From: attiasas Date: Mon, 27 Jul 2026 11:57:51 +0300 Subject: [PATCH 4/6] Use actual full path for validations --- commands/audit/audit.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/audit/audit.go b/commands/audit/audit.go index 53c2d95f4..df8927c25 100644 --- a/commands/audit/audit.go +++ b/commands/audit/audit.go @@ -1045,7 +1045,7 @@ func getScanResultsUiRoute(auditParams *AuditParams, uploadPath string) (string, ServerDetails: serverDetails, ProjectKey: auditParams.resultsContext.ProjectKey, GitContext: auditParams.GitContext(), - ScanResultArtifactPath: uploadPath, + ScanResultArtifactPath: fmt.Sprintf("%s/%s", auditParams.GetRtResultRepositoryWithProjectKey(), uploadPath), }) } From 3748d2a51d293540b49e9aab4c0464718b92d2d1 Mon Sep 17 00:00:00 2001 From: attiasas Date: Mon, 27 Jul 2026 12:07:51 +0300 Subject: [PATCH 5/6] fix static --- utils/xsc/scanresultsuiroute.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/xsc/scanresultsuiroute.go b/utils/xsc/scanresultsuiroute.go index f582babed..025816936 100644 --- a/utils/xsc/scanresultsuiroute.go +++ b/utils/xsc/scanresultsuiroute.go @@ -20,8 +20,8 @@ type ScanResultsUiRouteParams struct { } func GetScanResultsUiRoute(params *ScanResultsUiRouteParams) (string, error) { - if clientutils.ValidateMinimumVersion(clientutils.Xray, params.XrayVersion, xscServices.GetUIRouteAPIMinXrayVersion) != nil { - log.Debug(fmt.Sprintf("Minimal Xray version required for scan results UI route is '%s'. Skipping.", xscServices.GetUIRouteAPIMinXrayVersion)) + if err := clientutils.ValidateMinimumVersion(clientutils.Xray, params.XrayVersion, xscServices.GetUIRouteAPIMinXrayVersion); err != nil { + log.Debug(fmt.Sprintf("Getting scan results UI route is not supported on your current Xray version. %s", err.Error())) return "", nil } if params.GitContext == nil || params.ServerDetails == nil { From fc8d44d62e4cd8e48fc2d565f955dfc0d0c88740 Mon Sep 17 00:00:00 2001 From: attiasas Date: Mon, 27 Jul 2026 13:56:45 +0300 Subject: [PATCH 6/6] Update deps --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 839d2f0ee..ab50158ac 100644 --- a/go.mod +++ b/go.mod @@ -158,7 +158,7 @@ require ( ) // attiasas:feature/XRAY-132336-add-git-route-api -replace github.com/jfrog/jfrog-client-go => github.com/attiasas/jfrog-client-go v0.0.0-20260726073427-df350e2cf58d +replace github.com/jfrog/jfrog-client-go => github.com/attiasas/jfrog-client-go v0.0.0-20260726133026-33d5d7623ced // replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 master diff --git a/go.sum b/go.sum index 44ffc8e0d..14b94ca39 100644 --- a/go.sum +++ b/go.sum @@ -21,8 +21,8 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/attiasas/jfrog-client-go v0.0.0-20260726073427-df350e2cf58d h1:lwiC8BP/yZycOg81OrkWpxGqnoLYMZiKSspLnyPFWcU= -github.com/attiasas/jfrog-client-go v0.0.0-20260726073427-df350e2cf58d/go.mod h1:FHpjN1nTDoj96xd6obe27EOgGErqzU0rQgC96L3Ch9E= +github.com/attiasas/jfrog-client-go v0.0.0-20260726133026-33d5d7623ced h1:SkC7vMnFxdisIV6ijWyha2zyXaSGDwkWQyZDPWbpCTI= +github.com/attiasas/jfrog-client-go v0.0.0-20260726133026-33d5d7623ced/go.mod h1:FHpjN1nTDoj96xd6obe27EOgGErqzU0rQgC96L3Ch9E= github.com/beevik/etree v1.6.0 h1:u8Kwy8pp9D9XeITj2Z0XtA5qqZEmtJtuXZRQi+j03eE= github.com/beevik/etree v1.6.0/go.mod h1:bh4zJxiIr62SOf9pRzN7UUYaEDa9HEKafK25+sLc0Gc= github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M=