Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions azure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,30 @@ func buildAzureReposClient(t *testing.T, azureToken string) vcsclient.VcsClient
return azureClient
}

func buildAzureReposIntegrationTestDetails(t *testing.T) *IntegrationTestDetails {
func buildAzureReposIntegrationTestDetails(t *testing.T, useLocalRepo bool) *IntegrationTestDetails {
integrationRepoToken := getIntegrationToken(t, azureIntegrationTokenEnv)
testDetails := NewIntegrationTestDetails(integrationRepoToken, string(utils.AzureRepos), azureGitCloneUrl, "frogbot-test")
testDetails := NewIntegrationTestDetails(integrationRepoToken, string(utils.AzureRepos), azureGitCloneUrl, "frogbot-test", useLocalRepo)
testDetails.ApiEndpoint = azureApiEndpoint
return testDetails
}

func azureReposTestsInit(t *testing.T) (vcsclient.VcsClient, *IntegrationTestDetails) {
testDetails := buildAzureReposIntegrationTestDetails(t)
func azureReposTestsInit(t *testing.T, useLocalRepo bool) (vcsclient.VcsClient, *IntegrationTestDetails) {
testDetails := buildAzureReposIntegrationTestDetails(t, useLocalRepo)
azureClient := buildAzureReposClient(t, testDetails.GitToken)
return azureClient, testDetails
}

func TestAzureRepos_ScanPullRequestIntegration(t *testing.T) {
azureClient, testDetails := azureReposTestsInit(t)
azureClient, testDetails := azureReposTestsInit(t, false)
runScanPullRequestCmd(t, azureClient, testDetails)
}

func TestAzureRepos_ScanRepositoryIntegration(t *testing.T) {
azureClient, testDetails := azureReposTestsInit(t)
azureClient, testDetails := azureReposTestsInit(t, false)
runScanRepositoryCmd(t, azureClient, testDetails)
}

func TestAzureRepos_ScanRepositoryWithLocalDirIntegration(t *testing.T) {
azureClient, testDetails := azureReposTestsInit(t, true)
runScanRepositoryCmd(t, azureClient, testDetails)
}
17 changes: 11 additions & 6 deletions bitbucket_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ func buildBitbucketServerClient(t *testing.T, bitbucketServerToken string) vcscl
return bbClient
}

func buildBitbucketServerIntegrationTestDetails(t *testing.T) *IntegrationTestDetails {
func buildBitbucketServerIntegrationTestDetails(t *testing.T, useLocalRepo bool) *IntegrationTestDetails {
integrationRepoToken := getIntegrationToken(t, bitbucketServerIntegrationTokenEnv)
testDetails := NewIntegrationTestDetails(integrationRepoToken, string(utils.BitbucketServer), bitbucketServerGitCloneUrl, "FROG")
testDetails := NewIntegrationTestDetails(integrationRepoToken, string(utils.BitbucketServer), bitbucketServerGitCloneUrl, "FROG", useLocalRepo)
testDetails.ApiEndpoint = bitbucketServerApiEndpoint
return testDetails
}
Expand All @@ -53,19 +53,24 @@ func waitForConnection(t *testing.T) {
require.NoError(t, retryExecutor.Execute())
}

func bitbucketServerTestsInit(t *testing.T) (vcsclient.VcsClient, *IntegrationTestDetails) {
testDetails := buildBitbucketServerIntegrationTestDetails(t)
func bitbucketServerTestsInit(t *testing.T, useLocalRepo bool) (vcsclient.VcsClient, *IntegrationTestDetails) {
testDetails := buildBitbucketServerIntegrationTestDetails(t, useLocalRepo)
bbClient := buildBitbucketServerClient(t, testDetails.GitToken)
waitForConnection(t)
return bbClient, testDetails
}

func TestBitbucketServer_ScanPullRequestIntegration(t *testing.T) {
bbClient, testDetails := bitbucketServerTestsInit(t)
bbClient, testDetails := bitbucketServerTestsInit(t, false)
runScanPullRequestCmd(t, bbClient, testDetails)
}

func TestBitbucketServer_ScanRepositoryIntegration(t *testing.T) {
bbClient, testDetails := bitbucketServerTestsInit(t)
bbClient, testDetails := bitbucketServerTestsInit(t, false)
runScanRepositoryCmd(t, bbClient, testDetails)
}

func TestBitbucketServer_ScanRepositoryWithLocalDirIntegration(t *testing.T) {
bbClient, testDetails := bitbucketServerTestsInit(t, true)
runScanRepositoryCmd(t, bbClient, testDetails)
}
17 changes: 11 additions & 6 deletions github_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,28 @@ func buildGitHubClient(t *testing.T, githubToken string) vcsclient.VcsClient {
return githubClient
}

func buildGitHubIntegrationTestDetails(t *testing.T) *IntegrationTestDetails {
func buildGitHubIntegrationTestDetails(t *testing.T, useLocalRepo bool) *IntegrationTestDetails {
integrationRepoToken := getIntegrationToken(t, githubIntegrationTokenEnv)
return NewIntegrationTestDetails(integrationRepoToken, string(utils.GitHub), githubGitCloneUrl, "frogbot-test")
return NewIntegrationTestDetails(integrationRepoToken, string(utils.GitHub), githubGitCloneUrl, "frogbot-test", useLocalRepo)
}

func githubTestsInit(t *testing.T) (vcsclient.VcsClient, *IntegrationTestDetails) {
testDetails := buildGitHubIntegrationTestDetails(t)
func githubTestsInit(t *testing.T, useLocalRepo bool) (vcsclient.VcsClient, *IntegrationTestDetails) {
testDetails := buildGitHubIntegrationTestDetails(t, useLocalRepo)
githubClient := buildGitHubClient(t, testDetails.GitToken)
return githubClient, testDetails
}

func TestGitHub_ScanPullRequestIntegration(t *testing.T) {
githubClient, testDetails := githubTestsInit(t)
githubClient, testDetails := githubTestsInit(t, false)
runScanPullRequestCmd(t, githubClient, testDetails)
}

func TestGitHub_ScanRepositoryIntegration(t *testing.T) {
githubClient, testDetails := githubTestsInit(t)
githubClient, testDetails := githubTestsInit(t, false)
runScanRepositoryCmd(t, githubClient, testDetails)
}

func TestGitHub_ScanRepositoryWithLocalDirIntegration(t *testing.T) {
githubClient, testDetails := githubTestsInit(t, true)
runScanRepositoryCmd(t, githubClient, testDetails)
}
17 changes: 11 additions & 6 deletions gitlab_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,28 @@ func buildGitLabClient(t *testing.T, gitlabToken string) vcsclient.VcsClient {
return azureClient
}

func buildGitLabIntegrationTestDetails(t *testing.T) *IntegrationTestDetails {
func buildGitLabIntegrationTestDetails(t *testing.T, useLocalRepo bool) *IntegrationTestDetails {
integrationRepoToken := getIntegrationToken(t, gitlabIntegrationTokenEnv)
return NewIntegrationTestDetails(integrationRepoToken, string(utils.GitLab), gitlabGitCloneUrl, "frogbot-test2")
return NewIntegrationTestDetails(integrationRepoToken, string(utils.GitLab), gitlabGitCloneUrl, "frogbot-test2", useLocalRepo)
}

func gitlabTestsInit(t *testing.T) (vcsclient.VcsClient, *IntegrationTestDetails) {
testDetails := buildGitLabIntegrationTestDetails(t)
func gitlabTestsInit(t *testing.T, useLocalRepo bool) (vcsclient.VcsClient, *IntegrationTestDetails) {
testDetails := buildGitLabIntegrationTestDetails(t, useLocalRepo)
gitlabClient := buildGitLabClient(t, testDetails.GitToken)
return gitlabClient, testDetails
}

func TestGitLab_ScanPullRequestIntegration(t *testing.T) {
gitlabClient, testDetails := gitlabTestsInit(t)
gitlabClient, testDetails := gitlabTestsInit(t, false)
runScanPullRequestCmd(t, gitlabClient, testDetails)
}

func TestGitLab_ScanRepositoryIntegration(t *testing.T) {
gitlabClient, testDetails := gitlabTestsInit(t)
gitlabClient, testDetails := gitlabTestsInit(t, false)
runScanRepositoryCmd(t, gitlabClient, testDetails)
}

func TestGitLab_ScanRepositoryWithLocalDirIntegration(t *testing.T) {
gitlabClient, testDetails := gitlabTestsInit(t, true)
runScanRepositoryCmd(t, gitlabClient, testDetails)
}
66 changes: 46 additions & 20 deletions integrationutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package main
import (
"context"
"fmt"
"github.com/go-git/go-git/v5"
githttp "github.com/go-git/go-git/v5/plumbing/transport/http"
"github.com/jfrog/frogbot/v2/scanpullrequest"
"github.com/jfrog/frogbot/v2/scanrepository"
"github.com/jfrog/frogbot/v2/utils"
Expand Down Expand Up @@ -36,17 +38,19 @@ type IntegrationTestDetails struct {
ApiEndpoint string
PullRequestID string
CustomBranchName string
UseLocalRepo bool
}

func NewIntegrationTestDetails(token, gitProvider, gitCloneUrl, repoOwner string) *IntegrationTestDetails {
func NewIntegrationTestDetails(token, gitProvider, gitCloneUrl, repoOwner string, useLocalRepo bool) *IntegrationTestDetails {
return &IntegrationTestDetails{
GitProject: repoName,
RepoOwner: repoOwner,
RepoName: repoName,
GitToken: token,
GitUsername: "frogbot",
GitProvider: gitProvider,
GitCloneURL: gitCloneUrl,
GitProject: repoName,
RepoOwner: repoOwner,
RepoName: repoName,
GitToken: token,
GitUsername: "frogbot",
GitProvider: gitProvider,
GitCloneURL: gitCloneUrl,
UseLocalRepo: useLocalRepo,
}
}

Expand All @@ -71,18 +75,23 @@ func setIntegrationTestEnvs(t *testing.T, testDetails *IntegrationTestDetails) f
// Frogbot sanitizes all the environment variables that start with 'JF',
// so we restore them at the end of the test to avoid collisions with other tests
envRestoreFunc := getJfrogEnvRestoreFunc(t)
useLocalRepo := "false"
if testDetails.UseLocalRepo {
useLocalRepo = "true"
}
unsetEnvs := utils.SetEnvsAndAssertWithCallback(t, map[string]string{
utils.RequirementsFileEnv: "requirements.txt",
utils.GitPullRequestIDEnv: testDetails.PullRequestID,
utils.GitProvider: testDetails.GitProvider,
utils.GitTokenEnv: testDetails.GitToken,
utils.GitRepoEnv: testDetails.RepoName,
utils.GitRepoOwnerEnv: testDetails.RepoOwner,
utils.BranchNameTemplateEnv: testDetails.CustomBranchName,
utils.GitApiEndpointEnv: testDetails.ApiEndpoint,
utils.GitProjectEnv: testDetails.GitProject,
utils.GitUsernameEnv: testDetails.GitUsername,
utils.GitBaseBranchEnv: mainBranch,
utils.RequirementsFileEnv: "requirements.txt",
utils.GitPullRequestIDEnv: testDetails.PullRequestID,
utils.GitProvider: testDetails.GitProvider,
utils.GitTokenEnv: testDetails.GitToken,
utils.GitRepoEnv: testDetails.RepoName,
utils.GitRepoOwnerEnv: testDetails.RepoOwner,
utils.BranchNameTemplateEnv: testDetails.CustomBranchName,
utils.GitApiEndpointEnv: testDetails.ApiEndpoint,
utils.GitProjectEnv: testDetails.GitProject,
utils.GitUsernameEnv: testDetails.GitUsername,
utils.GitBaseBranchEnv: mainBranch,
utils.GitUseLocalRepositoryEnv: useLocalRepo,
})
return func() {
envRestoreFunc()
Expand Down Expand Up @@ -173,11 +182,28 @@ func runScanPullRequestCmd(t *testing.T, client vcsclient.VcsClient, testDetails
}

func runScanRepositoryCmd(t *testing.T, client vcsclient.VcsClient, testDetails *IntegrationTestDetails) {
_, restoreFunc := utils.ChangeToTempDirWithCallback(t)
testTempDir, restoreFunc := utils.ChangeToTempDirWithCallback(t)
defer func() {
assert.NoError(t, restoreFunc())
}()

// When testing using local repository clone the repository before the test starts so we can work with it as if it existed locally
if testDetails.UseLocalRepo {
cloneOptions := &git.CloneOptions{
URL: testDetails.GitCloneURL,
Auth: &githttp.BasicAuth{
Username: testDetails.GitUsername,
Password: testDetails.GitToken,
},
RemoteName: "origin",
ReferenceName: utils.GetFullBranchName("main"),
SingleBranch: true,
Depth: 1,
Tags: git.NoTags,
}
_, err := git.PlainClone(testTempDir, false, cloneOptions)
require.NoError(t, err)
}
timestamp := getTimestamp()
// Add a timestamp to the fixing pull requests, to identify them later
testDetails.CustomBranchName = "frogbot-{IMPACTED_PACKAGE}-{BRANCH_NAME_HASH}-" + timestamp
Expand Down
38 changes: 28 additions & 10 deletions scanrepository/scanrepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"errors"
"fmt"
biutils "github.com/jfrog/build-info-go/utils"
"os"
"path/filepath"
"regexp"
"strings"
Expand Down Expand Up @@ -80,17 +82,17 @@ func (cfp *ScanRepositoryCmd) scanAndFixBranch(repository *utils.Repository) (er
cfp.analyticsService.UpdateAndSendXscAnalyticsGeneralEventFinalize(err)
}()

clonedRepoDir, restoreBaseDir, err := cfp.cloneRepositoryAndCheckoutToBranch()
repoDir, restoreBaseDir, err := cfp.cloneRepositoryOrUseLocalAndCheckoutToBranch()
if err != nil {
return
}
cfp.baseWd = clonedRepoDir
cfp.baseWd = repoDir
defer func() {
// On dry run don't delete the folder as we want to validate results
if cfp.dryRun {
return
}
err = errors.Join(err, restoreBaseDir(), fileutils.RemoveTempDir(clonedRepoDir))
err = errors.Join(err, restoreBaseDir(), fileutils.RemoveTempDir(repoDir))
}()

// If MSI exists we always need to report events
Expand Down Expand Up @@ -476,7 +478,7 @@ func (cfp *ScanRepositoryCmd) preparePullRequestDetails(vulnerabilitiesDetails .
return pullRequestTitle, prBody, extraComments, nil
}

func (cfp *ScanRepositoryCmd) cloneRepositoryAndCheckoutToBranch() (tempWd string, restoreDir func() error, err error) {
func (cfp *ScanRepositoryCmd) cloneRepositoryOrUseLocalAndCheckoutToBranch() (tempWd string, restoreDir func() error, err error) {
if cfp.dryRun {
tempWd = filepath.Join(cfp.dryRunRepoPath, cfp.scanDetails.RepoName)
} else {
Expand All @@ -487,13 +489,29 @@ func (cfp *ScanRepositoryCmd) cloneRepositoryAndCheckoutToBranch() (tempWd strin
}
log.Debug("Created temp working directory:", tempWd)

// Clone the content of the repo to the new working directory
if err = cfp.gitManager.Clone(tempWd, cfp.scanDetails.BaseBranch()); err != nil {
return
if cfp.scanDetails.UseLocalRepository {
var curDir string
if curDir, err = os.Getwd(); err != nil {
return
}
if err = biutils.CopyDir(curDir, tempWd, true, nil); err != nil {
return
}
// 'CD' into the temp working directory
restoreDir, err = utils.Chdir(tempWd)
if err != nil {
return
}
// Set the current copied local dir as the local git repository we are working with
err = cfp.gitManager.SetLocalRepository()
} else {
// Clone the content of the repo to the new working directory
if err = cfp.gitManager.Clone(tempWd, cfp.scanDetails.BaseBranch()); err != nil {
return
}
// 'CD' into the temp working directory
restoreDir, err = utils.Chdir(tempWd)
}

// 'CD' into the temp working directory
restoreDir, err = utils.Chdir(tempWd)
return
}

Expand Down
11 changes: 6 additions & 5 deletions utils/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ const (
JfrogConfigProfileEnv = "JF_CONFIG_PROFILE"

// Git environment variables
GitProvider = "JF_GIT_PROVIDER"
GitRepoOwnerEnv = "JF_GIT_OWNER"
GitRepoEnv = "JF_GIT_REPO"
GitProjectEnv = "JF_GIT_PROJECT"
GitUsernameEnv = "JF_GIT_USERNAME"
GitProvider = "JF_GIT_PROVIDER"
GitRepoOwnerEnv = "JF_GIT_OWNER"
GitRepoEnv = "JF_GIT_REPO"
GitProjectEnv = "JF_GIT_PROJECT"
GitUsernameEnv = "JF_GIT_USERNAME"
GitUseLocalRepositoryEnv = "JF_USE_LOCAL_REPOSITORY"

// Git naming template environment variables
BranchNameTemplateEnv = "JF_BRANCH_NAME_TEMPLATE"
Expand Down
12 changes: 9 additions & 3 deletions utils/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func (gm *GitManager) SetRemoteGitUrl(remoteHttpsGitUrl string) (*GitManager, er
}

if gm.localGitRepository == nil {
if _, err = gm.SetLocalRepository(); err != nil {
if _, err = gm.SetLocalRepositoryAndRemoteName(); err != nil {
return gm, err
}
}
Expand All @@ -115,14 +115,20 @@ func (gm *GitManager) SetRemoteGitUrl(remoteHttpsGitUrl string) (*GitManager, er
return gm, nil
}

func (gm *GitManager) SetLocalRepository() (*GitManager, error) {
func (gm *GitManager) SetLocalRepositoryAndRemoteName() (*GitManager, error) {
var err error
// Re-initialize the repository and update remoteName
gm.remoteName = vcsutils.RemoteName
gm.localGitRepository, err = git.PlainOpen(".")
err = gm.SetLocalRepository()
return gm, err
}

func (gm *GitManager) SetLocalRepository() error {
var err error
gm.localGitRepository, err = git.PlainOpen(".")
return err
}

func (gm *GitManager) SetGitParams(gitParams *Git) (*GitManager, error) {
var err error
if gm.customTemplates, err = loadCustomTemplates(gitParams.CommitMessageTemplate, gitParams.BranchNameTemplate, gitParams.PullRequestTitleTemplate); err != nil {
Expand Down
6 changes: 6 additions & 0 deletions utils/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ type Git struct {
AggregateFixes bool `yaml:"aggregateFixes,omitempty"`
PullRequestDetails vcsclient.PullRequestInfo
RepositoryCloneUrl string
UseLocalRepository bool
}

func (g *Git) setDefaultsIfNeeded(gitParamsFromEnv *Git, commandName string) (err error) {
Expand Down Expand Up @@ -373,6 +374,11 @@ func (g *Git) extractScanRepositoryEnvParams(gitParamsFromEnv *Git) (err error)
return
}
}
if !g.UseLocalRepository {
if g.UseLocalRepository, err = getBoolEnv(GitUseLocalRepositoryEnv, false); err != nil {
return
}
}
return
}

Expand Down