diff --git a/commands/createfixpullrequests.go b/commands/createfixpullrequests.go index 283cbb223..4e1f21dd5 100644 --- a/commands/createfixpullrequests.go +++ b/commands/createfixpullrequests.go @@ -54,26 +54,24 @@ func (cfp *CreateFixPullRequestsCmd) scanAndFixRepository(repository *utils.Frog if err != nil { return err } - cfp.details = &utils.ScanDetails{ - XrayGraphScanParams: createXrayScanParams(repository.Watches, repository.JFrogProjectKey), - ServerDetails: &repository.Server, - Git: &repository.Git, - Client: client, - FailOnInstallationErrors: *repository.FailOnSecurityIssues, - Branch: branch, - ReleasesRepo: repository.JfrogReleasesRepo, - } - for _, project := range repository.Projects { - cfp.details.Project = project - cfp.aggregateFixes = repository.Git.AggregateFixes - projectFullPathWorkingDirs := getFullPathWorkingDirs(project.WorkingDirs, baseWd) + cfp.details = utils.NewScanDetails(client, &repository.Server, &repository.Git). + SetXrayGraphScanParams(repository.Watches, repository.JFrogProjectKey). + SetFailOnInstallationErrors(*repository.FailOnSecurityIssues). + SetBranch(branch). + SetReleasesRepo(repository.JfrogReleasesRepo). + SetFixableOnly(repository.FixableOnly). + SetMinSeverity(repository.MinSeverity) + cfp.aggregateFixes = repository.Git.AggregateFixes + for i := range repository.Projects { + cfp.details.Project = &repository.Projects[i] + projectFullPathWorkingDirs := getFullPathWorkingDirs(cfp.details.Project.WorkingDirs, baseWd) for _, fullPathWd := range projectFullPathWorkingDirs { scanResults, isMultipleRoots, err := cfp.scan(cfp.details, fullPathWd) if err != nil { return err } - err = utils.UploadScanToGitProvider(scanResults, repository, cfp.details.Branch, cfp.details.Client, isMultipleRoots) + err = utils.UploadScanToGitProvider(scanResults, repository, cfp.details.Branch(), cfp.details.Client(), isMultipleRoots) if err != nil { log.Warn(err) } @@ -151,8 +149,8 @@ func (cfp *CreateFixPullRequestsCmd) fixIssuesSeparatePRs(fixVersionsMap map[str log.Warn(err) } // After finishing to work on the current vulnerability, we go back to the base branch to start the next vulnerability fix - log.Info("Running git checkout to base branch:", cfp.details.Branch) - if err = cfp.gitManager.Checkout(cfp.details.Branch); err != nil { + log.Info("Running git checkout to base branch:", cfp.details.Branch()) + if err = cfp.gitManager.Checkout(cfp.details.Branch()); err != nil { return } } @@ -160,7 +158,6 @@ func (cfp *CreateFixPullRequestsCmd) fixIssuesSeparatePRs(fixVersionsMap map[str } func (cfp *CreateFixPullRequestsCmd) fixIssuesSinglePR(fixVersionsMap map[string]*utils.FixVersionInfo) (err error) { - successfullyFixedPackages := make(map[string]*utils.FixVersionInfo) log.Info("-----------------------------------------------------------------") log.Info("Start aggregated packages fix") aggregatedFixBranchName, err := cfp.gitManager.GenerateAggregatedFixBranchName(fixVersionsMap) @@ -174,13 +171,10 @@ func (cfp *CreateFixPullRequestsCmd) fixIssuesSinglePR(fixVersionsMap map[string for impactedPackage, fixVersionInfo := range fixVersionsMap { if err = cfp.updatePackageToFixedVersion(impactedPackage, fixVersionInfo); err != nil { log.Error("Could not fix impacted package", impactedPackage, "as part of the PR. Skipping it. Cause:", err.Error()) - } else { - log.Info("Successfully fixed", impactedPackage) - successfullyFixedPackages[impactedPackage] = fixVersionInfo } } - if err = cfp.openAggregatedPullRequest(aggregatedFixBranchName, successfullyFixedPackages); err != nil { + if err = cfp.openAggregatedPullRequest(aggregatedFixBranchName); err != nil { return fmt.Errorf("failed while creating aggreagted pull request. Error: \n%s", err.Error()) } return @@ -189,7 +183,7 @@ func (cfp *CreateFixPullRequestsCmd) fixIssuesSinglePR(fixVersionsMap map[string func (cfp *CreateFixPullRequestsCmd) fixSinglePackageAndCreatePR(impactedPackage string, fixVersionInfo *utils.FixVersionInfo) (err error) { log.Info("-----------------------------------------------------------------") log.Info("Start fixing", impactedPackage, "with", fixVersionInfo.FixVersion) - fixBranchName, err := cfp.gitManager.GenerateFixBranchName(cfp.details.Branch, impactedPackage, fixVersionInfo.FixVersion) + fixBranchName, err := cfp.gitManager.GenerateFixBranchName(cfp.details.Branch(), impactedPackage, fixVersionInfo.FixVersion) if err != nil { return } @@ -231,14 +225,14 @@ func (cfp *CreateFixPullRequestsCmd) openFixingPullRequest(impactedPackage, fixB } pullRequestTitle := cfp.gitManager.GeneratePullRequestTitle(impactedPackage, fixVersionInfo.FixVersion) - log.Info("Creating Pull Request form:", fixBranchName, " to:", cfp.details.Branch) + log.Info("Creating Pull Request form:", fixBranchName, " to:", cfp.details.Branch()) prBody := commitMessage + "\n\n" + utils.WhatIsFrogbotMd - return cfp.details.Client.CreatePullRequest(context.Background(), cfp.details.RepoOwner, cfp.details.RepoName, fixBranchName, cfp.details.Branch, pullRequestTitle, prBody) + return cfp.details.Client().CreatePullRequest(context.Background(), cfp.details.RepoOwner, cfp.details.RepoName, fixBranchName, cfp.details.Branch(), pullRequestTitle, prBody) } // When aggregate mode is active, there can be only one updated pull request to contain all the available fixes. // In case of an already opened pull request, Frogbot will only update the branch. -func (cfp *CreateFixPullRequestsCmd) openAggregatedPullRequest(fixBranchName string, versionsMap map[string]*utils.FixVersionInfo) (err error) { +func (cfp *CreateFixPullRequestsCmd) openAggregatedPullRequest(fixBranchName string) (err error) { log.Info("Checking if there are changes to commit") isClean, err := cfp.gitManager.IsClean() if err != nil { @@ -263,7 +257,7 @@ func (cfp *CreateFixPullRequestsCmd) openAggregatedPullRequest(fixBranchName str if !exists { log.Info("Creating Pull Request form:", fixBranchName, " to:", cfp.details.Branch) prBody := commitMessage + "\n\n" + utils.WhatIsFrogbotMd - return cfp.details.Client.CreatePullRequest(context.Background(), cfp.details.RepoOwner, cfp.details.RepoName, fixBranchName, cfp.details.Branch, utils.AggregatedPullRequestTitleTemplate, prBody) + return cfp.details.Client().CreatePullRequest(context.Background(), cfp.details.RepoOwner, cfp.details.RepoName, fixBranchName, cfp.details.Branch(), utils.AggregatedPullRequestTitleTemplate, prBody) } log.Info("Pull Request branch:", fixBranchName, "has been updated") return @@ -290,8 +284,7 @@ func (cfp *CreateFixPullRequestsCmd) cloneRepository() (tempWd string, restoreDi log.Debug("Created temp working directory:", tempWd) // Clone the content of the repo to the new working directory - err = cfp.gitManager.Clone(tempWd, cfp.details.Branch) - if err != nil { + if err = cfp.gitManager.Clone(tempWd, cfp.details.Branch()); err != nil { return } diff --git a/commands/createfixpullrequests_test.go b/commands/createfixpullrequests_test.go index f1a777c17..18acbdc0e 100644 --- a/commands/createfixpullrequests_test.go +++ b/commands/createfixpullrequests_test.go @@ -112,7 +112,7 @@ func getGenericFixPackageVersionFunc() FixPackagesTestFunc { return func(test packageFixTest) CreateFixPullRequestsCmd { return CreateFixPullRequestsCmd{ details: &utils.ScanDetails{ - Project: utils.Project{ + Project: &utils.Project{ PipRequirementsFile: test.packageDescriptor, WorkingDirs: []string{test.testPath}, }, @@ -267,8 +267,8 @@ func TestPackageTypeFromScan(t *testing.T) { frogbotParams.Projects[0].InstallCommandName = pkg.commandName frogbotParams.Projects[0].InstallCommandArgs = pkg.commandArgs scanSetup := utils.ScanDetails{ - XrayGraphScanParams: services.XrayGraphScanParams{}, - Project: frogbotParams.Projects[0], + XrayGraphScanParams: &services.XrayGraphScanParams{}, + Project: &frogbotParams.Projects[0], ServerDetails: &frogbotParams.Server, } scanResponse, _, err := testScan.scan(&scanSetup, tmpDir) diff --git a/commands/scanandfixrepos.go b/commands/scanandfixrepos.go index d751d83fb..19709e6c2 100644 --- a/commands/scanandfixrepos.go +++ b/commands/scanandfixrepos.go @@ -86,7 +86,7 @@ func (saf *ScanAndFixRepositories) downloadAndRunScanAndFix(repository *utils.Fr return cfp.scanAndFixRepository(repository, branch, client) } -func (saf ScanAndFixRepositories) setCommitBuildStatus(client vcsclient.VcsClient, repoConfig *utils.FrogbotRepoConfig, state vcsclient.CommitStatus, commitHash, description string) error { +func (saf *ScanAndFixRepositories) setCommitBuildStatus(client vcsclient.VcsClient, repoConfig *utils.FrogbotRepoConfig, state vcsclient.CommitStatus, commitHash, description string) error { if err := client.SetCommitStatus(context.Background(), state, repoConfig.RepoOwner, repoConfig.RepoName, commitHash, utils.FrogbotCreatorName, description, utils.CommitStatusDetailsUrl); err != nil { return fmt.Errorf("failed to mark last commit build status due to: %s", err.Error()) } @@ -96,7 +96,7 @@ func (saf ScanAndFixRepositories) setCommitBuildStatus(client vcsclient.VcsClien // Returns true if the latest commit hasn't been scanned // or the time passed from the last scan exceeded the configured value. -func (saf ScanAndFixRepositories) shouldScanLatestCommit(ctx context.Context, repoConfig *utils.FrogbotRepoConfig, client vcsclient.VcsClient, branch string) (shouldScan bool, commitHash string, err error) { +func (saf *ScanAndFixRepositories) shouldScanLatestCommit(ctx context.Context, repoConfig *utils.FrogbotRepoConfig, client vcsclient.VcsClient, branch string) (shouldScan bool, commitHash string, err error) { owner := repoConfig.RepoOwner repo := repoConfig.RepoName latestCommit, err := client.GetLatestCommit(ctx, owner, repo, branch) diff --git a/commands/scanpullrequest.go b/commands/scanpullrequest.go index 541537c3c..efdc2e277 100644 --- a/commands/scanpullrequest.go +++ b/commands/scanpullrequest.go @@ -74,20 +74,16 @@ func scanPullRequest(repoConfig *utils.FrogbotRepoConfig, client vcsclient.VcsCl } func auditPullRequest(repoConfig *utils.FrogbotRepoConfig, client vcsclient.VcsClient) ([]formats.VulnerabilityOrViolationRow, error) { - xrayScanParams := createXrayScanParams(repoConfig.Watches, repoConfig.JFrogProjectKey) var vulnerabilitiesRows []formats.VulnerabilityOrViolationRow - for _, project := range repoConfig.Projects { - scanSetup := &utils.ScanDetails{ - XrayGraphScanParams: xrayScanParams, - Project: project, - Client: client, - ServerDetails: &repoConfig.Server, - Git: &repoConfig.Git, - FailOnInstallationErrors: false, - Branch: repoConfig.Branches[0], - ReleasesRepo: repoConfig.JfrogReleasesRepo, - } - currentScan, isMultipleRoot, err := auditSource(scanSetup) + for i := range repoConfig.Projects { + scanDetails := utils.NewScanDetails(client, &repoConfig.Server, &repoConfig.Git). + SetProject(&repoConfig.Projects[i]). + SetBranch(repoConfig.Branches[0]). + SetReleasesRepo(repoConfig.JfrogReleasesRepo). + SetXrayGraphScanParams(repoConfig.Watches, repoConfig.JFrogProjectKey). + SetMinSeverity(repoConfig.MinSeverity). + SetFixableOnly(repoConfig.FixableOnly) + currentScan, isMultipleRoot, err := auditSource(scanDetails) if err != nil { return nil, err } @@ -101,8 +97,8 @@ func auditPullRequest(repoConfig *utils.FrogbotRepoConfig, client vcsclient.VcsC continue } // Audit target code - scanSetup.FailOnInstallationErrors = *repoConfig.FailOnSecurityIssues - previousScan, isMultipleRoot, err := auditTarget(scanSetup) + scanDetails.SetFailOnInstallationErrors(*repoConfig.FailOnSecurityIssues) + previousScan, isMultipleRoot, err := auditTarget(scanDetails) if err != nil { return nil, err } @@ -200,22 +196,6 @@ func createAllIssuesRows(currentScan []services.ScanResponse, isMultipleRoot boo return getScanVulnerabilitiesRows(violations, vulnerabilities, isMultipleRoot) } -func createXrayScanParams(watches []string, project string) (params services.XrayGraphScanParams) { - params.ScanType = services.Dependency - params.IncludeLicenses = false - if len(watches) > 0 { - params.Watches = watches - return - } - if project != "" { - params.ProjectKey = project - return - } - // No context was supplied, request from Xray to return all known vulnerabilities. - params.IncludeVulnerabilities = true - return -} - func auditSource(scanSetup *utils.ScanDetails) ([]services.ScanResponse, bool, error) { wd, err := os.Getwd() if err != nil { @@ -243,8 +223,8 @@ func getFullPathWorkingDirs(workingDirs []string, baseWd string) []string { func auditTarget(scanSetup *utils.ScanDetails) (res []services.ScanResponse, isMultipleRoot bool, err error) { // First download the target repo to temp dir - log.Info("Auditing ", scanSetup.Git.RepoName, scanSetup.Branch) - wd, cleanup, err := utils.DownloadRepoToTempDir(scanSetup.Client, scanSetup.Branch, scanSetup.Git) + log.Info("Auditing the", scanSetup.Git.RepoName, "repository on the", scanSetup.Branch(), "branch") + wd, cleanup, err := utils.DownloadRepoToTempDir(scanSetup.Client(), scanSetup.Branch(), scanSetup.Git) if err != nil { return } @@ -272,8 +252,10 @@ func runInstallAndAudit(scanSetup *utils.ScanDetails, workDirs ...string) (resul SetRequirementsFile(scanSetup.PipRequirementsFile). SetWorkingDirs(workDirs). SetDepsRepo(scanSetup.Repository). - SetReleasesRepo(scanSetup.ReleasesRepo). - SetIgnoreConfigFile(true) + SetReleasesRepo(scanSetup.ReleasesRepo()). + SetIgnoreConfigFile(true). + SetMinSeverityFilter(scanSetup.MinSeverityFilter()). + SetFixableOnly(scanSetup.FixableOnly()) results, isMultipleRoot, err = audit.GenericAudit(auditParams) if err != nil { return nil, false, err @@ -294,7 +276,7 @@ func runInstallIfNeeded(scanSetup *utils.ScanDetails, workDir string) (err error }() log.Info(fmt.Sprintf("Executing '%s %s' at %s", scanSetup.InstallCommandName, scanSetup.InstallCommandArgs, workDir)) output, err := runInstallCommand(scanSetup) - if err != nil && !scanSetup.FailOnInstallationErrors { + if err != nil && !scanSetup.FailOnInstallationErrors() { log.Info(installationCmdFailedErr, err.Error(), "\n", string(output)) // failOnInstallationErrors set to 'false' err = nil diff --git a/commands/scanpullrequest_test.go b/commands/scanpullrequest_test.go index 0d4704b31..5fc3a4412 100644 --- a/commands/scanpullrequest_test.go +++ b/commands/scanpullrequest_test.go @@ -35,29 +35,6 @@ const ( testProjConfigPathNoFail = "testdata/config/frogbot-config-test-proj-no-fail.yml" ) -func TestCreateXrayScanParams(t *testing.T) { - // Project - params := createXrayScanParams(nil, "") - assert.Empty(t, params.Watches) - assert.Equal(t, "", params.ProjectKey) - assert.True(t, params.IncludeVulnerabilities) - assert.False(t, params.IncludeLicenses) - - // Watches - params = createXrayScanParams([]string{"watch-1", "watch-2"}, "") - assert.Equal(t, []string{"watch-1", "watch-2"}, params.Watches) - assert.Equal(t, "", params.ProjectKey) - assert.False(t, params.IncludeVulnerabilities) - assert.False(t, params.IncludeLicenses) - - // Project - params = createXrayScanParams(nil, "project") - assert.Empty(t, params.Watches) - assert.Equal(t, "project", params.ProjectKey) - assert.False(t, params.IncludeVulnerabilities) - assert.False(t, params.IncludeLicenses) -} - func TestCreateVulnerabilitiesRows(t *testing.T) { // Previous scan with only one violation - XRAY-1 previousScan := services.ScanResponse{ @@ -412,9 +389,9 @@ func TestCreatePullRequestMessage(t *testing.T) { func TestRunInstallIfNeeded(t *testing.T) { scanSetup := utils.ScanDetails{ - Project: utils.Project{}, - FailOnInstallationErrors: true, + Project: &utils.Project{}, } + scanSetup.SetFailOnInstallationErrors(true) assert.NoError(t, runInstallIfNeeded(&scanSetup, "")) tmpDir, err := fileutils.CreateTempDir() assert.NoError(t, err) @@ -422,20 +399,20 @@ func TestRunInstallIfNeeded(t *testing.T) { InstallCommandName: "echo", InstallCommandArgs: []string{"Hello"}, } - scanSetup.Project = *params + scanSetup.Project = params assert.NoError(t, runInstallIfNeeded(&scanSetup, tmpDir)) scanSetup.InstallCommandName = "not-exist" scanSetup.InstallCommandArgs = []string{"1", "2"} - scanSetup.FailOnInstallationErrors = false + scanSetup.SetFailOnInstallationErrors(false) assert.NoError(t, runInstallIfNeeded(&scanSetup, tmpDir)) params = &utils.Project{ InstallCommandName: "not-existed", InstallCommandArgs: []string{"1", "2"}, } - scanSetup.Project = *params - scanSetup.FailOnInstallationErrors = true + scanSetup.Project = params + scanSetup.SetFailOnInstallationErrors(true) assert.Error(t, runInstallIfNeeded(&scanSetup, tmpDir)) } diff --git a/commands/testdata/config/frogbot-config-test-params.yml b/commands/testdata/config/frogbot-config-test-params.yml index 92e7b1c95..57b993bfc 100644 --- a/commands/testdata/config/frogbot-config-test-params.yml +++ b/commands/testdata/config/frogbot-config-test-params.yml @@ -10,6 +10,8 @@ scan: includeAllVulnerabilities: true failOnSecurityIssues: true + minSeverity: high + fixableOnly: true projects: - installCommand: nuget restore workingDirs: diff --git a/commands/utils/consts.go b/commands/utils/consts.go index 8f8022b65..dc50f4a67 100644 --- a/commands/utils/consts.go +++ b/commands/utils/consts.go @@ -58,6 +58,8 @@ const ( FailOnSecurityIssuesEnv = "JF_FAIL" UseWrapperEnv = "JF_USE_WRAPPER" DepsRepoEnv = "JF_DEPS_REPO" + MinSeverityEnv = "JF_MIN_SEVERITY" + FixableOnlyEnv = "JF_FIXABLE_ONLY" WatchesDelimiter = "," //#nosec G101 -- False positive - no hardcoded credentials. diff --git a/commands/utils/depsutil_test.go b/commands/utils/depsutil_test.go index e2aa4f233..68a22ad62 100644 --- a/commands/utils/depsutil_test.go +++ b/commands/utils/depsutil_test.go @@ -97,7 +97,7 @@ func TestResolveDependencies(t *testing.T) { tech: "npm", scanSetup: &ScanDetails{ ServerDetails: ¶ms, - Project: Project{ + Project: &Project{ InstallCommandName: "npm", InstallCommandArgs: []string{"install"}, }}, @@ -108,7 +108,7 @@ func TestResolveDependencies(t *testing.T) { tech: "yarn", scanSetup: &ScanDetails{ ServerDetails: ¶ms, - Project: Project{ + Project: &Project{ InstallCommandName: "yarn", InstallCommandArgs: []string{"install"}, }}, @@ -119,7 +119,7 @@ func TestResolveDependencies(t *testing.T) { tech: "dotnet", scanSetup: &ScanDetails{ ServerDetails: ¶ms, - Project: Project{ + Project: &Project{ Repository: "frogbot-nuget-remote-tests", InstallCommandName: "dotnet", InstallCommandArgs: []string{"restore"}, diff --git a/commands/utils/params.go b/commands/utils/params.go index 428429532..7b7e41819 100644 --- a/commands/utils/params.go +++ b/commands/utils/params.go @@ -3,6 +3,7 @@ package utils import ( "context" "fmt" + xrutils "github.com/jfrog/jfrog-cli-core/v2/xray/utils" "net/http" "os" "path/filepath" @@ -37,14 +38,16 @@ type FrogbotUtils struct { type FrogbotConfigAggregator []FrogbotRepoConfig // UnmarshalYaml uses the yaml.Unmarshaler interface to parse the yamlContent, and then sets default values if they weren't set by the user. -func (fca FrogbotConfigAggregator) UnmarshalYaml(yamlContent []byte) (result FrogbotConfigAggregator, err error) { +func (fca *FrogbotConfigAggregator) UnmarshalYaml(yamlContent []byte) (result FrogbotConfigAggregator, err error) { var configFile *FrogbotConfigAggregator - if err := yaml.Unmarshal(yamlContent, &configFile); err != nil { + if err = yaml.Unmarshal(yamlContent, &configFile); err != nil { return nil, err } for _, repository := range *configFile { - repository.Params, err = repository.Params.setDefaultsIfNeeded() - if err != nil { + if repository.MinSeverity, err = xrutils.GetSeveritiesFormat(repository.MinSeverity); err != nil { + return + } + if repository.Params, err = repository.Params.setDefaultsIfNeeded(); err != nil { return } result = append(result, repository) @@ -97,7 +100,9 @@ func (p *Project) setDefaultsIfNeeded() *Project { type Scan struct { IncludeAllVulnerabilities bool `yaml:"includeAllVulnerabilities,omitempty"` + FixableOnly bool `yaml:"fixableOnly,omitempty"` FailOnSecurityIssues *bool `yaml:"failOnSecurityIssues,omitempty"` + MinSeverity string `yaml:"minSeverity,omitempty"` Projects []Project `yaml:"projects,omitempty"` JfrogReleasesRepo string } @@ -194,7 +199,7 @@ func getConfigAggregator(client vcsclient.VcsClient, server *coreconfig.ServerDe // The getConfigFileContent function retrieves the frogbot-config.yml file content. // If the JF_GIT_REPO and JF_GIT_OWNER environment variables are set, this function will attempt to retrieve the frogbot-config.yml file from the target repository based on these variables. -// If these variables are not set, this function will attempt to retrieve the frogbot-config.yml file from the current working directory. +// If these variables aren't set, this function will attempt to retrieve the frogbot-config.yml file from the current working directory. func getConfigFileContent(client vcsclient.VcsClient) (configFileContent []byte, err error) { var targetConfigContent []byte configFileContent, err = readConfigFromTarget(client) @@ -269,26 +274,35 @@ func extractGitParamsFromEnv() (*Git, error) { var err error gitParams := Git{} // Non-mandatory Git Api Endpoint, if not set, default values will be used. - _ = ReadParamFromEnv(GitApiEndpointEnv, &gitParams.ApiEndpoint) + e := &ErrMissingEnv{} + if err = readParamFromEnv(GitApiEndpointEnv, &gitParams.ApiEndpoint); err != nil && !e.IsMissingEnvErr(err) { + return nil, err + } if gitParams.GitProvider, err = extractVcsProviderFromEnv(); err != nil { return nil, err } - if err = ReadParamFromEnv(GitRepoOwnerEnv, &gitParams.RepoOwner); err != nil { + if err = readParamFromEnv(GitRepoOwnerEnv, &gitParams.RepoOwner); err != nil { + return nil, err + } + if err = readParamFromEnv(GitTokenEnv, &gitParams.Token); err != nil { return nil, err } - if err = ReadParamFromEnv(GitTokenEnv, &gitParams.Token); err != nil { + // Username is only mandatory for Bitbucket Server when using the scan-and-fix-repos command. + if err = readParamFromEnv(GitUsernameEnv, &gitParams.Username); err != nil && !e.IsMissingEnvErr(err) { return nil, err } - // Username is only mandatory for Bitbucket server on the scan-and-fix-repos command. - _ = ReadParamFromEnv(GitUsernameEnv, &gitParams.Username) // Repo name validation will be performed later, this env is mandatory in case there is no config file. - _ = ReadParamFromEnv(GitRepoEnv, &gitParams.RepoName) - if err := ReadParamFromEnv(GitProjectEnv, &gitParams.GitProject); err != nil && gitParams.GitProvider == vcsutils.AzureRepos { + if err = readParamFromEnv(GitRepoEnv, &gitParams.RepoName); err != nil && !e.IsMissingEnvErr(err) { + return nil, err + } + if err = readParamFromEnv(GitProjectEnv, &gitParams.GitProject); err != nil && gitParams.GitProvider == vcsutils.AzureRepos { return nil, err } // Non-mandatory git branch and pr id. var branch string - _ = ReadParamFromEnv(GitBaseBranchEnv, &branch) + if err = readParamFromEnv(GitBaseBranchEnv, &branch); err != nil && !e.IsMissingEnvErr(err) { + return nil, err + } gitParams.Branches = append(gitParams.Branches, branch) if pullRequestIDString := getTrimmedEnv(GitPullRequestIDEnv); pullRequestIDString != "" { gitParams.PullRequestID, err = strconv.Atoi(pullRequestIDString) @@ -305,7 +319,7 @@ func extractGitParamsFromEnv() (*Git, error) { return &gitParams, err } -func ReadParamFromEnv(envKey string, paramValue *string) error { +func readParamFromEnv(envKey string, paramValue *string) error { *paramValue = getTrimmedEnv(envKey) if *paramValue == "" { return &ErrMissingEnv{envKey} @@ -425,6 +439,7 @@ func setProjectInstallCommand(installCommand string, project *Project) { func extractRepoParamsFromEnv(repo *FrogbotRepoConfig) error { var err error + if repo.IncludeAllVulnerabilities, err = getBoolEnv(IncludeAllVulnerabilitiesEnv, false); err != nil { return err } @@ -434,14 +449,27 @@ func extractRepoParamsFromEnv(repo *FrogbotRepoConfig) error { } repo.FailOnSecurityIssues = &failOnSecurityIssues // Non-mandatory Xray context params + e := &ErrMissingEnv{} var watches string - _ = ReadParamFromEnv(jfrogWatchesEnv, &watches) + if err = readParamFromEnv(jfrogWatchesEnv, &watches); err != nil && !e.IsMissingEnvErr(err) { + return err + } if watches != "" { // Remove spaces if exists watches = strings.ReplaceAll(watches, " ", "") repo.Watches = strings.Split(watches, WatchesDelimiter) } - _ = ReadParamFromEnv(jfrogProjectEnv, &repo.JFrogProjectKey) + if err = readParamFromEnv(jfrogProjectEnv, &repo.JFrogProjectKey); err != nil && !e.IsMissingEnvErr(err) { + return err + } + // Results filtering environment variables + if err = readParamFromEnv(MinSeverityEnv, &repo.MinSeverity); err != nil && !e.IsMissingEnvErr(err) { + return err + } + if repo.MinSeverity, err = xrutils.GetSeveritiesFormat(repo.MinSeverity); err != nil { + return err + } + repo.FixableOnly, err = getBoolEnv(FixableOnlyEnv, false) return err } @@ -458,7 +486,8 @@ func getBoolEnv(envKey string, defaultValue bool) (bool, error) { return defaultValue, nil } -// In case frogbot-config.yml does not exist, newConfigAggregatorFromEnv generates a FrogbotConfigAggregator with the environment variables values. +// In case frogbot-config.yml doesn't exist, +// newConfigAggregatorFromEnv generates a FrogbotConfigAggregator with the environment variables values. func newConfigAggregatorFromEnv(gitParams *Git, server *coreconfig.ServerDetails, releasesRepo string) (FrogbotConfigAggregator, error) { // The repo name must be set as a part of the envs. if gitParams.RepoName == "" { @@ -484,16 +513,25 @@ func newConfigAggregatorFromEnv(gitParams *Git, server *coreconfig.ServerDetails // readConfigFromTarget reads the .frogbot/frogbot-config.yml from the target repository func readConfigFromTarget(client vcsclient.VcsClient) (configContent []byte, err error) { + e := &ErrMissingEnv{} var branch string - _ = ReadParamFromEnv(GitBaseBranchEnv, &branch) + if err = readParamFromEnv(GitBaseBranchEnv, &branch); err != nil && !e.IsMissingEnvErr(err) { + return nil, err + } var repo string - _ = ReadParamFromEnv(GitRepoEnv, &repo) + if err = readParamFromEnv(GitRepoEnv, &repo); err != nil && !e.IsMissingEnvErr(err) { + return nil, err + } var owner string - _ = ReadParamFromEnv(GitRepoOwnerEnv, &owner) + if err = readParamFromEnv(GitRepoOwnerEnv, &owner); err != nil && !e.IsMissingEnvErr(err) { + return nil, err + } + if repo != "" && owner != "" { if branch == "" { log.Debug(GitBaseBranchEnv, "is missing. Assuming that the", FrogbotConfigFile, "file exists on default branch") } + log.Debug("Downloading", FrogbotConfigFile, "from target", owner, "/", repo, "/", branch) gitFrogbotConfigPath := fmt.Sprintf("%s/%s", frogbotConfigDir, FrogbotConfigFile) var statusCode int diff --git a/commands/utils/params_test.go b/commands/utils/params_test.go index 45d63a1a7..fdc2141ff 100644 --- a/commands/utils/params_test.go +++ b/commands/utils/params_test.go @@ -139,6 +139,8 @@ func TestExtractAndAssertRepoParams(t *testing.T) { GitBaseBranchEnv: "dev", GitPullRequestIDEnv: "1", GitAggregateFixesEnv: "true", + MinSeverityEnv: "high", + FixableOnlyEnv: "true", }) defer func() { assert.NoError(t, SanitizeEnv()) @@ -161,6 +163,8 @@ func TestExtractAndAssertRepoParams(t *testing.T) { assert.Equal(t, "myPullRequests", templates.pullRequestTitleTemplate) assert.Equal(t, "custom commit title", templates.commitMessageTemplate) assert.Equal(t, "this is my branch ${BRANCH_NAME_HASH}", templates.branchNameTemplate) + assert.Equal(t, "High", repo.MinSeverity) + assert.True(t, repo.FixableOnly) assert.Equal(t, true, repo.AggregateFixes) assert.ElementsMatch(t, []string{"watch-2", "watch-1"}, repo.Watches) @@ -260,6 +264,8 @@ func TestGenerateConfigAggregatorFromEnv(t *testing.T) { DepsRepoEnv: "deps-remote", IncludeAllVulnerabilitiesEnv: "true", FailOnSecurityIssuesEnv: "false", + MinSeverityEnv: "medium", + FixableOnlyEnv: "true", }) defer func() { assert.NoError(t, SanitizeEnv()) @@ -290,6 +296,8 @@ func TestGenerateConfigAggregatorFromEnv(t *testing.T) { assert.Equal(t, "releases-remote", repo.JfrogReleasesRepo) assert.ElementsMatch(t, repo.Watches, []string{"watch-1", "watch-2", "watch-3"}) assert.Equal(t, false, *repo.FailOnSecurityIssues) + assert.Equal(t, "Medium", repo.MinSeverity) + assert.Equal(t, true, repo.FixableOnly) assert.Equal(t, gitParams.RepoOwner, repo.RepoOwner) assert.Equal(t, gitParams.Token, repo.Token) assert.Equal(t, gitParams.ApiEndpoint, repo.ApiEndpoint) diff --git a/commands/utils/scandetails.go b/commands/utils/scandetails.go new file mode 100644 index 000000000..b93a73df2 --- /dev/null +++ b/commands/utils/scandetails.go @@ -0,0 +1,101 @@ +package utils + +import ( + "github.com/jfrog/froggit-go/vcsclient" + "github.com/jfrog/jfrog-cli-core/v2/utils/config" + "github.com/jfrog/jfrog-client-go/xray/services" +) + +type ScanDetails struct { + *Project + *Git + *services.XrayGraphScanParams + *config.ServerDetails + client vcsclient.VcsClient + failOnInstallationErrors bool + fixableOnly bool + minSeverityFilter string + branch string + releasesRepo string +} + +func NewScanDetails(client vcsclient.VcsClient, server *config.ServerDetails, git *Git) *ScanDetails { + return &ScanDetails{client: client, ServerDetails: server, Git: git} +} + +func (sc *ScanDetails) SetFailOnInstallationErrors(toFail bool) *ScanDetails { + sc.failOnInstallationErrors = toFail + return sc +} + +func (sc *ScanDetails) SetProject(project *Project) *ScanDetails { + sc.Project = project + return sc +} + +func (sc *ScanDetails) SetXrayGraphScanParams(watches []string, jfrogProjectKey string) *ScanDetails { + sc.XrayGraphScanParams = createXrayScanParams(watches, jfrogProjectKey) + return sc +} + +func (sc *ScanDetails) SetFixableOnly(fixable bool) *ScanDetails { + sc.fixableOnly = fixable + return sc +} + +func (sc *ScanDetails) SetMinSeverity(minSeverity string) *ScanDetails { + sc.minSeverityFilter = minSeverity + return sc +} + +func (sc *ScanDetails) SetBranch(branch string) *ScanDetails { + sc.branch = branch + return sc +} + +func (sc *ScanDetails) SetReleasesRepo(releasesRepo string) *ScanDetails { + sc.releasesRepo = releasesRepo + return sc +} + +func (sc *ScanDetails) Client() vcsclient.VcsClient { + return sc.client +} + +func (sc *ScanDetails) Branch() string { + return sc.branch +} + +func (sc *ScanDetails) ReleasesRepo() string { + return sc.releasesRepo +} + +func (sc *ScanDetails) FailOnInstallationErrors() bool { + return sc.failOnInstallationErrors +} + +func (sc *ScanDetails) FixableOnly() bool { + return sc.fixableOnly +} + +func (sc *ScanDetails) MinSeverityFilter() string { + return sc.minSeverityFilter +} + +func createXrayScanParams(watches []string, project string) (params *services.XrayGraphScanParams) { + params = &services.XrayGraphScanParams{ + ScanType: services.Dependency, + IncludeLicenses: false, + } + if len(watches) > 0 { + params.Watches = watches + return + } + if project != "" { + params.ProjectKey = project + return + } + // No context was supplied. We therefore request from Xray to return all known vulnerabilities. + params.IncludeVulnerabilities = true + return +} diff --git a/commands/utils/scandetails_test.go b/commands/utils/scandetails_test.go new file mode 100644 index 000000000..35d0e46a2 --- /dev/null +++ b/commands/utils/scandetails_test.go @@ -0,0 +1,30 @@ +package utils + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestCreateXrayScanParams(t *testing.T) { + // Project + scanDetails := &ScanDetails{} + scanDetails.SetXrayGraphScanParams(nil, "") + assert.Empty(t, scanDetails.Watches) + assert.Equal(t, "", scanDetails.ProjectKey) + assert.True(t, scanDetails.IncludeVulnerabilities) + assert.False(t, scanDetails.IncludeLicenses) + + // Watches + scanDetails.SetXrayGraphScanParams([]string{"watch-1", "watch-2"}, "") + assert.Equal(t, []string{"watch-1", "watch-2"}, scanDetails.Watches) + assert.Equal(t, "", scanDetails.ProjectKey) + assert.False(t, scanDetails.IncludeVulnerabilities) + assert.False(t, scanDetails.IncludeLicenses) + + // Project + scanDetails.SetXrayGraphScanParams(nil, "project") + assert.Empty(t, scanDetails.Watches) + assert.Equal(t, "project", scanDetails.ProjectKey) + assert.False(t, scanDetails.IncludeVulnerabilities) + assert.False(t, scanDetails.IncludeLicenses) +} diff --git a/commands/utils/utils.go b/commands/utils/utils.go index d842ca697..9cdd1ccd5 100644 --- a/commands/utils/utils.go +++ b/commands/utils/utils.go @@ -47,10 +47,6 @@ var BuildToolsDependenciesMap = map[coreutils.Technology][]string{ coreutils.Pip: {"pip", "setuptools", "wheel"}, } -type ErrMissingEnv struct { - VariableName string -} - type ErrUnsupportedIndirectFix struct { PackageName string } @@ -77,8 +73,17 @@ func (fvi *FixVersionInfo) UpdateFixVersionIfMax(newFixVersion string) { } } -func (m *ErrMissingEnv) Error() string { - return fmt.Sprintf("'%s' environment variable is missing", m.VariableName) +type ErrMissingEnv struct { + VariableName string +} + +func (e *ErrMissingEnv) Error() string { + return fmt.Sprintf("'%s' environment variable is missing", e.VariableName) +} + +// IsMissingEnvErr returns true if err is a type of ErrMissingEnv, otherwise false +func (e *ErrMissingEnv) IsMissingEnvErr(err error) bool { + return errors.As(err, &e) } type ErrMissingConfig struct { @@ -89,17 +94,6 @@ func (e *ErrMissingConfig) Error() string { return fmt.Sprintf("config file is missing: %s", e.missingReason) } -type ScanDetails struct { - services.XrayGraphScanParams - Project - *config.ServerDetails - *Git - Client vcsclient.VcsClient - FailOnInstallationErrors bool - Branch string - ReleasesRepo string -} - // The OutputWriter interface allows Frogbot output to be written in an appropriate way for each git provider. // Some git providers support markdown only partially, whereas others support it fully. type OutputWriter interface { diff --git a/docs/install-azure-repos.md b/docs/install-azure-repos.md index 1ea375942..f5486be80 100644 --- a/docs/install-azure-repos.md +++ b/docs/install-azure-repos.md @@ -148,6 +148,15 @@ To install Frogbot on Azure Repos repositories, follow these steps. # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" inputs: script: | diff --git a/docs/install-bitbucket-server.md b/docs/install-bitbucket-server.md index fcc18b9f7..d7e782419 100644 --- a/docs/install-bitbucket-server.md +++ b/docs/install-bitbucket-server.md @@ -149,7 +149,16 @@ // [Optional, Default: "FALSE"] // If TRUE, Frogbot creates a single pull request with all the fixes. // If FALSE, Frogbot creates a separate pull request for each fix. - // JF_GIT_AGGREGATE_FIXES: "FALSE" + // JF_GIT_AGGREGATE_FIXES= "FALSE" + + // [Optional, Default: "FALSE"] + // Handle vulnerabilities with fix versions only + // JF_FIXABLE_ONLY= "TRUE" + + // [Optional] + // Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + // The following values are accepted: Low, Medium, High or Critical + // JF_MIN_SEVERITY= "" } stages { diff --git a/docs/install-github.md b/docs/install-github.md index 29e4228d1..7bd02532b 100644 --- a/docs/install-github.md +++ b/docs/install-github.md @@ -70,146 +70,154 @@ - Create a Jenkinsfile with the below template content under the root of your **Frogbot Management Repository**.
Template + + ```groovy + // Run the job once an hour + CRON_SETTINGS = '''* */1 * * *''' + pipeline { + agent any + triggers { + cron(CRON_SETTINGS) + } + environment { + // [Mandatory] + // JFrog platform URL (This functionality requires version 3.29.0 or above of Xray) + JF_URL = credentials("JF_URL") + + // [Mandatory if JF_USER and JF_PASSWORD are not provided] + // JFrog access token with 'read' permissions for Xray + JF_ACCESS_TOKEN= credentials("JF_ACCESS_TOKEN") + + // [Mandatory if JF_ACCESS_TOKEN is not provided] + // JFrog user and password with 'read' permissions for Xray + // JF_USER = credentials("JF_USER") + // JF_PASSWORD = credentials("JF_PASSWORD") + + // [Mandatory] + // GitHub enterprise server access token with the following permissions: + // Read and Write access to code, pull requests, security events, and workflows + JF_GIT_TOKEN = credentials("FROGBOT_GIT_TOKEN") + JF_GIT_PROVIDER = "github" + + // [Mandatory] + // GitHub enterprise server organization namespace + JF_GIT_OWNER = "" + + // [Mandatory] + // API endpoint to GitHub enterprise server + JF_GIT_API_ENDPOINT = "" + + // [Optional] + // If the machine that runs Frogbot has no access to the internet, set the name of a remote repository + // in Artifactory, which proxies https://releases.jfrog.io + // The 'frogbot' executable and other tools it needs will be downloaded through this repository. + // JF_RELEASES_REPO= "" + - ```groovy - // Run the job once an hour - CRON_SETTINGS = '''* */1 * * *''' - pipeline { - agent any - triggers { - cron(CRON_SETTINGS) - } - environment { - // [Mandatory] - // JFrog platform URL (This functionality requires version 3.29.0 or above of Xray) - JF_URL = credentials("JF_URL") - - // [Mandatory if JF_USER and JF_PASSWORD are not provided] - // JFrog access token with 'read' permissions for Xray - JF_ACCESS_TOKEN= credentials("JF_ACCESS_TOKEN") - - // [Mandatory if JF_ACCESS_TOKEN is not provided] - // JFrog user and password with 'read' permissions for Xray - // JF_USER = credentials("JF_USER") - // JF_PASSWORD = credentials("JF_PASSWORD") - - // [Mandatory] - // GitHub enterprise server access token with the following permissions: - // Read and Write access to code, pull requests, security events, and workflows - JF_GIT_TOKEN = credentials("FROGBOT_GIT_TOKEN") - JF_GIT_PROVIDER = "github" - - // [Mandatory] - // GitHub enterprise server organization namespace - JF_GIT_OWNER = "" - - // [Mandatory] - // API endpoint to GitHub enterprise server - JF_GIT_API_ENDPOINT = "" - - // [Optional] - // If the machine that runs Frogbot has no access to the internet, set the name of a remote repository - // in Artifactory, which proxies https://releases.jfrog.io - // The 'frogbot' executable and other tools it needs will be downloaded through this repository. - // JF_RELEASES_REPO= "" - - - - - ////////////////////////////////////////////////////////////////////////// - // If your project uses a 'frogbot-config.yml' file, you can define // - // the following variables inside the file, instead of here. // - ////////////////////////////////////////////////////////////////////////// - - // [Mandatory if the two conditions below are met] - // 1. The project uses yarn 2, NuGet or .NET to download its dependencies - // 2. The `installCommand` variable isn't set in your frogbot-config.yml file. - // - // The command that installs the project dependencies (e.g "nuget restore") - JF_INSTALL_DEPS_CMD = "" - - // [Optional, default: "."] - // Relative path to the root of the project in the Git repository - // JF_WORKING_DIR= path/to/project/dir - - // [Optional] - // Xray Watches. Learn more about them here: https://www.jfrog.com/confluence/display/JFROG/Configuring+Xray+Watches - // JF_WATCHES= ,... - - // [Optional] - // JFrog project. Learn more about it here: https://www.jfrog.com/confluence/display/JFROG/Projects - // JF_PROJECT= - - // [Optional, default: "FALSE"] - // Displays all existing vulnerabilities, including the ones that were added by the pull request. - // JF_INCLUDE_ALL_VULNERABILITIES= "TRUE" - - // [Optional, default: "TRUE"] - // Fails the Frogbot task if any security issue is found. - // JF_FAIL= "FALSE" - // [Optional, default: "TRUE"] - // Relative path to a Pip requirements.txt file. If not set, the python project's dependencies are determined and scanned using the project setup.py file. - // JF_REQUIREMENTS_FILE= "" + + ////////////////////////////////////////////////////////////////////////// + // If your project uses a 'frogbot-config.yml' file, you can define // + // the following variables inside the file, instead of here. // + ////////////////////////////////////////////////////////////////////////// + + // [Mandatory if the two conditions below are met] + // 1. The project uses yarn 2, NuGet or .NET to download its dependencies + // 2. The `installCommand` variable isn't set in your frogbot-config.yml file. + // + // The command that installs the project dependencies (e.g "nuget restore") + JF_INSTALL_DEPS_CMD = "" + + // [Optional, default: "."] + // Relative path to the root of the project in the Git repository + // JF_WORKING_DIR= path/to/project/dir + + // [Optional] + // Xray Watches. Learn more about them here: https://www.jfrog.com/confluence/display/JFROG/Configuring+Xray+Watches + // JF_WATCHES= ,... + + // [Optional] + // JFrog project. Learn more about it here: https://www.jfrog.com/confluence/display/JFROG/Projects + // JF_PROJECT= + + // [Optional, default: "FALSE"] + // Displays all existing vulnerabilities, including the ones that were added by the pull request. + // JF_INCLUDE_ALL_VULNERABILITIES= "TRUE" + + // [Optional, default: "TRUE"] + // Fails the Frogbot task if any security issue is found. + // JF_FAIL= "FALSE" - // [Optional, Default: "TRUE"] - // Use Gradle wrapper. - // JF_USE_WRAPPER= "FALSE" - - // [Optional] - // Frogbot will download the project dependencies if they're not cached locally. To download the - // dependencies from a virtual repository in Artifactory, set the name of of the repository. There's no - // need to set this value, if it is set in the frogbot-config.yml file. - // JF_DEPS_REPO= "" + // [Optional, default: "TRUE"] + // Relative path to a Pip requirements.txt file. If not set, the python project's dependencies are determined and scanned using the project setup.py file. + // JF_REQUIREMENTS_FILE= "" - // [Optional] - // Template for the branch name generated by Frogbot when creating pull requests with fixes. - // The template must include ${BRANCH_NAME_HASH}, to ensure that the generated branch name is unique. - // The template can optionally include the ${IMPACTED_PACKAGE} and ${FIX_VERSION} variables. - // JF_BRANCH_NAME_TEMPLATE= "frogbot-${IMPACTED_PACKAGE}-${BRANCH_NAME_HASH}" - - // [Optional] - // Template for the commit message generated by Frogbot when creating pull requests with fixes - // The template can optionally include the ${IMPACTED_PACKAGE} and ${FIX_VERSION} variables. - // JF_COMMIT_MESSAGE_TEMPLATE= "Upgrade ${IMPACTED_PACKAGE} to ${FIX_VERSION}" - - // [Optional] - // Template for the pull request title generated by Frogbot when creating pull requests with fixes. - // The template can optionally include the ${IMPACTED_PACKAGE} and ${FIX_VERSION} variables. - // JF_PULL_REQUEST_TITLE_TEMPLATE= "[🐸 Frogbot] Upgrade ${IMPACTED_PACKAGE} to to ${FIX_VERSION}" - - // [Optional, Default: "FALSE"] - // If TRUE, Frogbot creates a single pull request with all the fixes. - // If FALSE, Frogbot creates a separate pull request for each fix. - // JF_GIT_AGGREGATE_FIXES: "FALSE" - } - stages { - stage('Download Frogbot') { - steps { - // For Linux / MacOS runner: - sh """ curl -fLg "https://releases.jfrog.io/artifactory/frogbot/v2/[RELEASE]/getFrogbot.sh" | sh""" - // For Windows runner: - // powershell """iwr https://releases.jfrog.io/artifactory/frogbot/v2/[RELEASE]/frogbot-windows-amd64/frogbot.exe -OutFile .\frogbot.exe""" - } - } - stage('Scan Pull Requests') { - steps { - sh "./frogbot scan-pull-requests" - // For Windows runner: - // powershell """.\frogbot.exe scan-pull-requests""" - } - } - stage('Scan and Fix Repos') { - steps { - sh "./frogbot scan-and-fix-repos" - // For Windows runner: - // powershell """.\frogbot.exe scan-and-fix-repos""" - } - } - } - } - ``` -
+ // [Optional, Default: "TRUE"] + // Use Gradle wrapper. + // JF_USE_WRAPPER= "FALSE" + + // [Optional] + // Frogbot will download the project dependencies if they're not cached locally. To download the + // dependencies from a virtual repository in Artifactory, set the name of of the repository. There's no + // need to set this value, if it is set in the frogbot-config.yml file. + // JF_DEPS_REPO= "" + + // [Optional] + // Template for the branch name generated by Frogbot when creating pull requests with fixes. + // The template must include ${BRANCH_NAME_HASH}, to ensure that the generated branch name is unique. + // The template can optionally include the ${IMPACTED_PACKAGE} and ${FIX_VERSION} variables. + // JF_BRANCH_NAME_TEMPLATE= "frogbot-${IMPACTED_PACKAGE}-${BRANCH_NAME_HASH}" + + // [Optional] + // Template for the commit message generated by Frogbot when creating pull requests with fixes + // The template can optionally include the ${IMPACTED_PACKAGE} and ${FIX_VERSION} variables. + // JF_COMMIT_MESSAGE_TEMPLATE= "Upgrade ${IMPACTED_PACKAGE} to ${FIX_VERSION}" + + // [Optional] + // Template for the pull request title generated by Frogbot when creating pull requests with fixes. + // The template can optionally include the ${IMPACTED_PACKAGE} and ${FIX_VERSION} variables. + // JF_PULL_REQUEST_TITLE_TEMPLATE= "[🐸 Frogbot] Upgrade ${IMPACTED_PACKAGE} to to ${FIX_VERSION}" + + // [Optional, Default: "FALSE"] + // If TRUE, Frogbot creates a single pull request with all the fixes. + // If FALSE, Frogbot creates a separate pull request for each fix. + // JF_GIT_AGGREGATE_FIXES= "FALSE" + + // [Optional, Default: "FALSE"] + // Handle vulnerabilities with fix versions only + // JF_FIXABLE_ONLY= "TRUE" + + // [Optional] + // Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + // The following values are accepted: Low, Medium, High or Critical + // JF_MIN_SEVERITY= "" + } + stages { + stage('Download Frogbot') { + steps { + // For Linux / MacOS runner: + sh """ curl -fLg "https://releases.jfrog.io/artifactory/frogbot/v2/[RELEASE]/getFrogbot.sh" | sh""" + // For Windows runner: + // powershell """iwr https://releases.jfrog.io/artifactory/frogbot/v2/[RELEASE]/frogbot-windows-amd64/frogbot.exe -OutFile .\frogbot.exe""" + } + } + stage('Scan Pull Requests') { + steps { + sh "./frogbot scan-pull-requests" + // For Windows runner: + // powershell """.\frogbot.exe scan-pull-requests""" + } + } + stage('Scan and Fix Repos') { + steps { + sh "./frogbot scan-and-fix-repos" + // For Windows runner: + // powershell """.\frogbot.exe scan-and-fix-repos""" + } + } + } + } + ``` - In the Jenkinsfile, set the values of all the mandatory variables. @@ -222,4 +230,5 @@ - Make sure all the build tools used to build the project are installed on the Jenkins agent. + diff --git a/docs/install-gitlab.md b/docs/install-gitlab.md index a6fd52a36..f50dbe297 100644 --- a/docs/install-gitlab.md +++ b/docs/install-gitlab.md @@ -128,7 +128,15 @@ frogbot-scan: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" - + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" script: # For Linux / MacOS runner: - curl -fLg "https://releases.jfrog.io/artifactory/frogbot/v2/[RELEASE]/getFrogbot.sh" | sh diff --git a/docs/templates/.frogbot/frogbot-config.yml b/docs/templates/.frogbot/frogbot-config.yml index e7f390b05..f35d5a16c 100644 --- a/docs/templates/.frogbot/frogbot-config.yml +++ b/docs/templates/.frogbot/frogbot-config.yml @@ -44,6 +44,15 @@ # Frogbot does not fail the task if security issues are found and this parameter is set to false # failOnSecurityIssues: false + # [Default: false] + # Handle vulnerabilities with fix versions only + # fixableOnly: true + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # minSeverity: "" + # List of subprojects / project dirs inside the Git repository projects: # [Mandatory if the two conditions below are met] @@ -59,7 +68,7 @@ # - "." # [Mandatory for pip only if using requirements file, Default: pip install .] - # The requirements file name that used to install dependencies in case of pip package manager + # The requirements file name that is used to install dependencies in case of pip package manager # pipRequirementsFile: "" # [Default: true] diff --git a/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-go.yml b/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-go.yml index 8602928ed..3b52e3c99 100644 --- a/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-go.yml +++ b/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-go.yml @@ -106,3 +106,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" diff --git a/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-maven.yml b/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-maven.yml index af27f10c1..a887a6feb 100644 --- a/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-maven.yml +++ b/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-maven.yml @@ -107,3 +107,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" diff --git a/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-npm.yml b/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-npm.yml index 4fb4ebef7..33d1ab496 100644 --- a/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-npm.yml +++ b/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-npm.yml @@ -113,3 +113,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" \ No newline at end of file diff --git a/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-pip.yml b/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-pip.yml index 32d12d9e6..7842ab6b1 100644 --- a/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-pip.yml +++ b/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-pip.yml @@ -110,3 +110,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" \ No newline at end of file diff --git a/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-pipenv.yml b/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-pipenv.yml index 6f21ca2f2..630574d95 100644 --- a/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-pipenv.yml +++ b/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-pipenv.yml @@ -113,3 +113,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" \ No newline at end of file diff --git a/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-poetry.yml b/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-poetry.yml index 20c611188..4f1669181 100644 --- a/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-poetry.yml +++ b/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-poetry.yml @@ -108,3 +108,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" \ No newline at end of file diff --git a/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-yarn.yml b/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-yarn.yml index 4fb4ebef7..33d1ab496 100644 --- a/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-yarn.yml +++ b/docs/templates/github-actions/scan-and-fix/frogbot-scan-and-fix-yarn.yml @@ -113,3 +113,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" \ No newline at end of file diff --git a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-dotnet.yml b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-dotnet.yml index a4f430f7c..2f41bc761 100644 --- a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-dotnet.yml +++ b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-dotnet.yml @@ -97,3 +97,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If false, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" \ No newline at end of file diff --git a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-go.yml b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-go.yml index 25f70a99e..d159fe3d3 100644 --- a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-go.yml +++ b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-go.yml @@ -91,3 +91,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" \ No newline at end of file diff --git a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-gradle.yml b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-gradle.yml index b9923fc29..db87f7ee0 100644 --- a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-gradle.yml +++ b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-gradle.yml @@ -95,3 +95,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" \ No newline at end of file diff --git a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-maven.yml b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-maven.yml index 6f5d6bacb..099b47bd2 100644 --- a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-maven.yml +++ b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-maven.yml @@ -92,3 +92,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" \ No newline at end of file diff --git a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-npm.yml b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-npm.yml index 05820e6b4..4d702d853 100644 --- a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-npm.yml +++ b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-npm.yml @@ -98,3 +98,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" \ No newline at end of file diff --git a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-nuget.yml b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-nuget.yml index 4ae48bc54..0c2ab0b6f 100644 --- a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-nuget.yml +++ b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-nuget.yml @@ -97,3 +97,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" \ No newline at end of file diff --git a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-pip.yml b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-pip.yml index a6a9d430e..8e178ac58 100644 --- a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-pip.yml +++ b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-pip.yml @@ -94,3 +94,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" \ No newline at end of file diff --git a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-pipenv.yml b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-pipenv.yml index 4ea56d2fc..34eadf9a0 100644 --- a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-pipenv.yml +++ b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-pipenv.yml @@ -96,3 +96,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" \ No newline at end of file diff --git a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-poetry.yml b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-poetry.yml index be6cb88f3..b0235b017 100644 --- a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-poetry.yml +++ b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-poetry.yml @@ -92,3 +92,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" \ No newline at end of file diff --git a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-yarn.yml b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-yarn.yml index 024b23230..acd07b9fc 100644 --- a/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-yarn.yml +++ b/docs/templates/github-actions/scan-pull-request/frogbot-scan-pr-yarn.yml @@ -98,3 +98,12 @@ jobs: # If TRUE, Frogbot creates a single pull request with all the fixes. # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" \ No newline at end of file diff --git a/docs/templates/jfrog-pipelines/pipelines-dotnet.yml b/docs/templates/jfrog-pipelines/pipelines-dotnet.yml index a57eeed23..05a941c2d 100644 --- a/docs/templates/jfrog-pipelines/pipelines-dotnet.yml +++ b/docs/templates/jfrog-pipelines/pipelines-dotnet.yml @@ -137,6 +137,15 @@ pipelines: # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" + execution: onExecute: - cd $res_frogbotGitRepo_resourcePath diff --git a/docs/templates/jfrog-pipelines/pipelines-go.yml b/docs/templates/jfrog-pipelines/pipelines-go.yml index 313ee3edb..584ccc843 100644 --- a/docs/templates/jfrog-pipelines/pipelines-go.yml +++ b/docs/templates/jfrog-pipelines/pipelines-go.yml @@ -139,6 +139,15 @@ pipelines: # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" + execution: onExecute: - cd $res_frogbotGitRepo_resourcePath diff --git a/docs/templates/jfrog-pipelines/pipelines-gradle.yml b/docs/templates/jfrog-pipelines/pipelines-gradle.yml index c74d74ed4..ed6a8bb10 100644 --- a/docs/templates/jfrog-pipelines/pipelines-gradle.yml +++ b/docs/templates/jfrog-pipelines/pipelines-gradle.yml @@ -143,6 +143,15 @@ pipelines: # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" + execution: onExecute: - cd $res_frogbotGitRepo_resourcePath diff --git a/docs/templates/jfrog-pipelines/pipelines-maven.yml b/docs/templates/jfrog-pipelines/pipelines-maven.yml index 7ded0ba84..93c35c2bf 100644 --- a/docs/templates/jfrog-pipelines/pipelines-maven.yml +++ b/docs/templates/jfrog-pipelines/pipelines-maven.yml @@ -131,6 +131,15 @@ pipelines: # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" + execution: onExecute: - cd $res_frogbotGitRepo_resourcePath diff --git a/docs/templates/jfrog-pipelines/pipelines-npm.yml b/docs/templates/jfrog-pipelines/pipelines-npm.yml index 564f11c89..972890118 100644 --- a/docs/templates/jfrog-pipelines/pipelines-npm.yml +++ b/docs/templates/jfrog-pipelines/pipelines-npm.yml @@ -154,6 +154,15 @@ pipelines: # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" + execution: onExecute: - cd $res_frogbotGitRepo_resourcePath diff --git a/docs/templates/jfrog-pipelines/pipelines-pip.yml b/docs/templates/jfrog-pipelines/pipelines-pip.yml index 45b462045..7f7a8a20b 100644 --- a/docs/templates/jfrog-pipelines/pipelines-pip.yml +++ b/docs/templates/jfrog-pipelines/pipelines-pip.yml @@ -141,6 +141,15 @@ pipelines: # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" + execution: onExecute: - cd $res_frogbotGitRepo_resourcePath diff --git a/docs/templates/jfrog-pipelines/pipelines-pipenv.yml b/docs/templates/jfrog-pipelines/pipelines-pipenv.yml index 8ac9d44f8..9ea2d1635 100644 --- a/docs/templates/jfrog-pipelines/pipelines-pipenv.yml +++ b/docs/templates/jfrog-pipelines/pipelines-pipenv.yml @@ -134,6 +134,15 @@ pipelines: # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" + execution: onExecute: - cd $res_frogbotGitRepo_resourcePath diff --git a/docs/templates/jfrog-pipelines/pipelines-poetry.yml b/docs/templates/jfrog-pipelines/pipelines-poetry.yml index 2d62e7ce6..1b134afc4 100644 --- a/docs/templates/jfrog-pipelines/pipelines-poetry.yml +++ b/docs/templates/jfrog-pipelines/pipelines-poetry.yml @@ -134,6 +134,15 @@ pipelines: # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" + execution: onExecute: - cd $res_frogbotGitRepo_resourcePath diff --git a/docs/templates/jfrog-pipelines/pipelines-yarn2.yml b/docs/templates/jfrog-pipelines/pipelines-yarn2.yml index 0edd5166f..fc59eec24 100644 --- a/docs/templates/jfrog-pipelines/pipelines-yarn2.yml +++ b/docs/templates/jfrog-pipelines/pipelines-yarn2.yml @@ -138,6 +138,15 @@ pipelines: # If FALSE, Frogbot creates a separate pull request for each fix. # JF_GIT_AGGREGATE_FIXES: "FALSE" + # [Optional, Default: "FALSE"] + # Handle vulnerabilities with fix versions only + # JF_FIXABLE_ONLY: "TRUE" + + # [Optional] + # Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests + # The following values are accepted: Low, Medium, High or Critical + # JF_MIN_SEVERITY: "" + execution: onExecute: - cd $res_frogbotGitRepo_resourcePath diff --git a/go.mod b/go.mod index 3a3876fd4..c9c86a2eb 100644 --- a/go.mod +++ b/go.mod @@ -5,16 +5,17 @@ go 1.19 require ( github.com/go-git/go-git/v5 v5.6.1 github.com/golang/mock v1.6.0 - github.com/jfrog/build-info-go v1.9.2 + github.com/jfrog/build-info-go v1.9.3 github.com/jfrog/froggit-go v1.7.1 - github.com/jfrog/gofrog v1.2.5 - github.com/jfrog/jfrog-cli-core/v2 v2.31.2 - github.com/jfrog/jfrog-client-go v1.28.2 + github.com/jfrog/gofrog v1.3.0 + github.com/jfrog/jfrog-cli-core/v2 v2.32.1 + github.com/jfrog/jfrog-client-go v1.28.3 github.com/mholt/archiver/v3 v3.5.1 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.8.2 github.com/urfave/cli/v2 v2.25.1 github.com/xeipuuv/gojsonschema v1.2.0 + golang.org/x/exp v0.0.0-20230418202329-0354be287a23 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -27,7 +28,7 @@ require ( github.com/VividCortex/ewma v1.2.0 // indirect github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect github.com/acomagu/bufpipe v1.0.4 // indirect - github.com/andybalholm/brotli v1.0.1 // indirect + github.com/andybalholm/brotli v1.0.5 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/c-bata/go-prompt v0.2.5 // indirect github.com/chzyer/readline v1.5.1 // indirect @@ -98,7 +99,6 @@ require ( github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect golang.org/x/crypto v0.8.0 // indirect - golang.org/x/exp v0.0.0-20230418202329-0354be287a23 // indirect golang.org/x/net v0.9.0 // indirect golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect golang.org/x/sys v0.7.0 // indirect @@ -111,8 +111,10 @@ require ( gopkg.in/warnings.v0 v0.1.2 // indirect ) -//replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.13.2-0.20230404093739-610cb3af8862 +//replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.15.3-0.20230501142220-e6a6becf0848 -//replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.15.3-0.20230404095831-ce76a2622e41 +//replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20230430083747-590ae14f9dca + +//replace github.com/jfrog/gofrog => github.com/jfrog/gofrog v1.2.6-0.20230418122323-2bf299dd6d27 //replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go v1.8.9-0.20230403064815-ea83b399ac8e diff --git a/go.sum b/go.sum index 8a38b803c..d1903e200 100644 --- a/go.sum +++ b/go.sum @@ -53,8 +53,9 @@ github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpH github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= -github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= +github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= @@ -222,16 +223,16 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i github.com/jedib0t/go-pretty/v6 v6.4.6 h1:v6aG9h6Uby3IusSSEjHaZNXpHFhzqMmjXcPq1Rjl9Jw= github.com/jedib0t/go-pretty/v6 v6.4.6/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= -github.com/jfrog/build-info-go v1.9.2 h1:gSX9PH3whFcAMtM9dlPxRE7u9YuYcx8IkfVXQKRjWw0= -github.com/jfrog/build-info-go v1.9.2/go.mod h1:hHXyLsG0SW1jQa4g6q8x2LGAvvX/MMqWVFTcIUAF2PI= +github.com/jfrog/build-info-go v1.9.3 h1:ZpVcNM4hH+r6dK0ERdSNaizuZALPgSdE29Da1Iki1fo= +github.com/jfrog/build-info-go v1.9.3/go.mod h1:GbuFS+viHCKZYx9nWHYu7ab1DgQkFdtVN3BJPUNb2D4= github.com/jfrog/froggit-go v1.7.1 h1:1LBOjB3qZCW2Ys/GqG52zYHlmtHICaprDgwLvBbJy+w= github.com/jfrog/froggit-go v1.7.1/go.mod h1:xfsfQXzSaAM04RV9IyU5heBiRrsm2oS6rFCfEofQr6U= -github.com/jfrog/gofrog v1.2.5 h1:jCgJC0iGQ8bU7jCC+YEFJTNINyngApIrhd8BjZAVRIE= -github.com/jfrog/gofrog v1.2.5/go.mod h1:o00tSRff6IapTgaCMuX1Cs9MH08Y1JqnsKgRtx91Gc4= -github.com/jfrog/jfrog-cli-core/v2 v2.31.2 h1:vrYy6sJzu7AG6l1mnMrnOiy+KQk5Q2SHE9jxpo9oaTY= -github.com/jfrog/jfrog-cli-core/v2 v2.31.2/go.mod h1:FCDD9AMBQyUtfc517U3nDIeFteEXVZmpINn0x93y6nA= -github.com/jfrog/jfrog-client-go v1.28.2 h1:o8qx7NI3IVCXH1l0of8bdjIPf+ojgct5WMJ06HE3UMQ= -github.com/jfrog/jfrog-client-go v1.28.2/go.mod h1:ULqUGW9pie9xZCDoFO3JyWr6wRR/rp+qzOvAXzIVr+0= +github.com/jfrog/gofrog v1.3.0 h1:o4zgsBZE4QyDbz2M7D4K6fXPTBJht+8lE87mS9bw7Gk= +github.com/jfrog/gofrog v1.3.0/go.mod h1:IFMc+V/yf7rA5WZ74CSbXe+Lgf0iApEQLxRZVzKRUR0= +github.com/jfrog/jfrog-cli-core/v2 v2.32.1 h1:dsCMMX5H2J1/VcCqogWJjLqy+hlKpTEi4gy55w0etDw= +github.com/jfrog/jfrog-cli-core/v2 v2.32.1/go.mod h1:humz/0YFeD9P0T50QP2812AIKy8UNQ8OsWIfiHbdPM8= +github.com/jfrog/jfrog-client-go v1.28.3 h1:r/p1tZzaW0afLAk5LBbrcaW4nuL1fcQXpxr9BKfxrNc= +github.com/jfrog/jfrog-client-go v1.28.3/go.mod h1:xX+2RY7AZn9LtNOFlp5pEkWy/e0oCtCq/T/RNQ+dVIg= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= diff --git a/schema/frogbot-schema.json b/schema/frogbot-schema.json index 6bbcba7fb..0ec2e445f 100644 --- a/schema/frogbot-schema.json +++ b/schema/frogbot-schema.json @@ -97,6 +97,19 @@ "description": "Set to true to fail the job if security issues were found.", "title": "Fail on Security Issues" }, + "minSeverity": { + "type": "string", + "default": ["Show all severities"], + "description": "Set the minimum severity for vulnerabilities that should be fixed and commented on in pull requests.", + "title": "Minimum vulnerability severity to filter", + "examples": ["low, medium, high, critical"] + }, + "fixableOnly": { + "type": "boolean", + "default": ["false"], + "description": "Handle vulnerabilities with fix versions only.", + "title": "Handle vulnerabilities with fix versions only" + }, "projects": { "type": ["array", "null"], "title": "Projects in Git Repository",