Skip to content

Commit c6f07fa

Browse files
authored
Adding support for bitbucket cloud (#1298)
1 parent 75ecfbf commit c6f07fa

9 files changed

Lines changed: 48 additions & 14 deletions

File tree

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
github.com/golang/mock v1.6.0
99
github.com/google/go-github/v45 v45.2.0
1010
github.com/jfrog/build-info-go v1.13.1-0.20260429070557-93b98034d295
11-
github.com/jfrog/froggit-go v1.21.1
11+
github.com/jfrog/froggit-go v1.22.0
1212
github.com/jfrog/gofrog v1.7.6
1313
github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260504054219-ba16d20c7b0f
1414
github.com/jfrog/jfrog-cli-security v1.28.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ github.com/jfrog/archiver/v3 v3.6.3 h1:hkAmPjBw393tPmQ07JknLNWFNZjXdy2xFEnOW9wwO
140140
github.com/jfrog/archiver/v3 v3.6.3/go.mod h1:5V9l+Fte30Y4qe9dUOAd3yNTf8lmtVNuhKNrvI8PMhg=
141141
github.com/jfrog/build-info-go v1.13.1-0.20260429070557-93b98034d295 h1:EH0h86KwGvNHWyEBQoHoU9WfMMKy1GJ6jJQNmfy6E0U=
142142
github.com/jfrog/build-info-go v1.13.1-0.20260429070557-93b98034d295/go.mod h1:+OCtMb22/D+u7Wne5lzkjJjaWr0LRZcHlDwTH86Mpwo=
143-
github.com/jfrog/froggit-go v1.21.1 h1:I/XUOO6GQ1d/rmBlM361F8T654C3ohIWrpw23xNL9JY=
144-
github.com/jfrog/froggit-go v1.21.1/go.mod h1:umBiakJB0CSPFfe0AHVaC3n9xsmUT7NGkDCny3bRchI=
143+
github.com/jfrog/froggit-go v1.22.0 h1:eeN5F8sOUo+h2cXkzArAu4nvSdjkDTAZtgqwrct70qg=
144+
github.com/jfrog/froggit-go v1.22.0/go.mod h1:wRDryqyp3oe+eHgME2mpnEQmO8XBECIPagFwj0nHmdI=
145145
github.com/jfrog/gofrog v1.7.6 h1:QmfAiRzVyaI7JYGsB7cxfAJePAZTzFz0gRWZSE27c6s=
146146
github.com/jfrog/gofrog v1.7.6/go.mod h1:ntr1txqNOZtHplmaNd7rS4f8jpA5Apx8em70oYEe7+4=
147147
github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYLipdsOFMY=

scanrepository/scanrepository.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,8 @@ func (sr *ScanRepositoryCmd) fixSinglePackageAndCreatePR(repository *utils.Repos
295295
return
296296
}
297297
if existsInRemote {
298-
log.Info(fmt.Sprintf("A pull request updating the dependency '%s' to version '%s' already exists. Skipping...", vulnDetails.ImpactedDependencyName, vulnDetails.SuggestedFixedVersion))
298+
log.Info(fmt.Sprintf("Skipping fix pull request for dependency '%s' to version '%s': a fix branch already exists. If the pull request was previously closed, delete the fix branch to allow a new one to be created.",
299+
vulnDetails.ImpactedDependencyName, vulnDetails.SuggestedFixedVersion))
299300
return
300301
}
301302

utils/comment.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ import (
55
"errors"
66
"fmt"
77
"regexp"
8+
"slices"
89
"sort"
910
"strconv"
1011

1112
"github.com/jfrog/froggit-go/vcsclient"
13+
"github.com/jfrog/froggit-go/vcsutils"
1214
"github.com/jfrog/gofrog/datastructures"
1315
"github.com/jfrog/jfrog-cli-security/utils/formats"
1416
"github.com/jfrog/jfrog-cli-security/utils/results"
@@ -51,7 +53,12 @@ func HandlePullRequestCommentsAfterScan(issues *issues.ScansIssuesCollection, re
5153

5254
// Add summary scan comment
5355
if issues.IssuesExists(repo.FrogbotConfig.ShowSecretsAsPrComment) || !repo.FrogbotConfig.HideSuccessBannerForNoIssues {
54-
for _, comment := range generatePullRequestSummaryComment(*issues, resultContext, repo.FrogbotConfig.ShowSecretsAsPrComment, repo.OutputWriter) {
56+
comments := generatePullRequestSummaryComment(*issues, resultContext, repo.FrogbotConfig.ShowSecretsAsPrComment, repo.OutputWriter)
57+
if repo.OutputWriter.VcsProvider() == vcsutils.BitbucketCloud {
58+
// Bitbucket Cloud Activity feed displays comments newest-first, so post in reverse to keep summary on top.
59+
slices.Reverse(comments)
60+
}
61+
for _, comment := range comments {
5562
if err = client.AddPullRequestComment(context.Background(), repo.RepoOwner, repo.RepoName, comment, pullRequestID); err != nil {
5663
err = errors.New("couldn't add pull request comment: " + err.Error())
5764
return

utils/consts.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const (
1515
GitHub vcsProvider = "github"
1616
GitLab vcsProvider = "gitlab"
1717
BitbucketServer vcsProvider = "bitbucketServer"
18+
BitbucketCloud vcsProvider = "bitbucketCloud"
1819
AzureRepos vcsProvider = "azureRepos"
1920

2021
// CI providers params

utils/getconfiguration.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,9 @@ func extractGitParamsFromEnvs() (*Git, error) {
410410
return nil, err
411411
}
412412

413-
// Mandatory only for Bitbucket Server, this authentication detail is required for performing git operations.
413+
// Mandatory for Bitbucket Server. For Bitbucket Cloud, username is required only when using
414+
// Basic Auth (Atlassian API token or app password). Bearer token users (Repository/Workspace
415+
// Access Tokens) leave this unset and authenticate via JF_GIT_TOKEN alone.
414416
if err = readParamFromEnv(GitBitBucketUsernameEnv, &gitEnvParams.Username); err != nil && gitEnvParams.GitProvider == vcsutils.BitbucketServer {
415417
return nil, err
416418
}
@@ -463,13 +465,15 @@ func extractVcsProviderFromEnv() (vcsutils.VcsProvider, error) {
463465
return vcsutils.GitHub, nil
464466
case string(GitLab):
465467
return vcsutils.GitLab, nil
466-
// For backward compatibility, we are accepting also "bitbucket server"
468+
// For backward compatibility, we are accepting also "bitbucket server" and "bitbucket cloud"
467469
case string(BitbucketServer), "bitbucket server":
468470
return vcsutils.BitbucketServer, nil
471+
case string(BitbucketCloud):
472+
return vcsutils.BitbucketCloud, nil
469473
case string(AzureRepos):
470474
return vcsutils.AzureRepos, nil
471475
}
472-
return 0, fmt.Errorf("%s should be one of: '%s', '%s', '%s' or '%s'", GitProvider, GitHub, GitLab, BitbucketServer, AzureRepos)
476+
return 0, fmt.Errorf("%s should be one of: '%s', '%s', '%s', '%s' or '%s'", GitProvider, GitHub, GitLab, BitbucketServer, BitbucketCloud, AzureRepos)
473477
}
474478

475479
func SanitizeEnv() error {

utils/getconfiguration_test.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,33 @@ func TestExtractVcsProviderFromEnv(t *testing.T) {
122122
assert.NoError(t, err)
123123
assert.Equal(t, vcsutils.BitbucketServer, vcsProvider)
124124

125+
SetEnvAndAssert(t, map[string]string{GitProvider: string(BitbucketCloud)})
126+
vcsProvider, err = extractVcsProviderFromEnv()
127+
assert.NoError(t, err)
128+
assert.Equal(t, vcsutils.BitbucketCloud, vcsProvider)
129+
125130
SetEnvAndAssert(t, map[string]string{GitProvider: string(AzureRepos)})
126131
vcsProvider, err = extractVcsProviderFromEnv()
127132
assert.NoError(t, err)
128133
assert.Equal(t, vcsutils.AzureRepos, vcsProvider)
129134
}
130135

136+
func TestExtractGitParamsFromEnvs_BitbucketCloudNoUsernameRequired(t *testing.T) {
137+
defer func() {
138+
assert.NoError(t, SanitizeEnv())
139+
}()
140+
SetEnvAndAssert(t, map[string]string{
141+
GitRepoEnv: "frogbot",
142+
GitProvider: string(BitbucketCloud),
143+
GitRepoOwnerEnv: "jfrog",
144+
GitTokenEnv: "token123",
145+
})
146+
// Bitbucket Cloud supports Bearer token auth (Repository/Workspace Access Tokens) without a username.
147+
params, err := extractGitParamsFromEnvs()
148+
assert.NoError(t, err)
149+
assert.Empty(t, params.Username)
150+
}
151+
131152
func TestExtractGitParamsFromEnvs(t *testing.T) {
132153
defer func() {
133154
assert.NoError(t, SanitizeEnv())
@@ -138,7 +159,7 @@ func TestExtractGitParamsFromEnvs(t *testing.T) {
138159

139160
SetEnvAndAssert(t, map[string]string{GitRepoEnv: "frogbot"})
140161
_, err = extractGitParamsFromEnvs()
141-
assert.EqualError(t, err, "JF_GIT_PROVIDER should be one of: 'github', 'gitlab', 'bitbucketServer' or 'azureRepos'")
162+
assert.EqualError(t, err, "JF_GIT_PROVIDER should be one of: 'github', 'gitlab', 'bitbucketServer', 'bitbucketCloud' or 'azureRepos'")
142163

143164
SetEnvAndAssert(t, map[string]string{GitProvider: "github"})
144165
_, err = extractGitParamsFromEnvs()

utils/git.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package utils
33
import (
44
"errors"
55
"fmt"
6+
"github.com/jfrog/jfrog-client-go/utils/errorutils"
67
"net/http"
78
"regexp"
89
"strings"
@@ -22,7 +23,6 @@ import (
2223
"github.com/go-git/go-git/v5/plumbing/format/gitignore"
2324
"github.com/go-git/go-git/v5/plumbing/object"
2425
githttp "github.com/go-git/go-git/v5/plumbing/transport/http"
25-
"github.com/jfrog/jfrog-client-go/utils/errorutils"
2626
"github.com/jfrog/jfrog-client-go/utils/log"
2727
)
2828

@@ -377,7 +377,6 @@ func (gm *GitManager) Push(force bool, branchName string) error {
377377
// On dry run do not push to any remote
378378
return nil
379379
}
380-
// Pushing to remote
381380
if err := gm.localGitRepository.Push(&git.PushOptions{
382381
RemoteName: gm.remoteName,
383382
Auth: gm.auth,
@@ -525,9 +524,10 @@ func (gm *GitManager) GetRemoteName() string {
525524
}
526525

527526
func toBasicAuth(username, token string) *githttp.BasicAuth {
528-
// The username can be anything except for an empty string
527+
// Bitbucket Cloud Repository/Workspace Access Tokens require "x-token-auth" as the git username.
528+
// This is also safe for all other providers where the username is irrelevant for token auth.
529529
if username == "" {
530-
username = "username"
530+
username = "x-token-auth"
531531
}
532532
// Bitbucket server username starts with ~ prefix as the project key. We need to trim it for the authentication
533533
username = strings.TrimPrefix(username, "~")

utils/outputwriter/outputwriter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ func (mo *MarkdownOutput) SetSizeLimit(client vcsclient.VcsClient) {
101101
}
102102

103103
func GetCompatibleOutputWriter(provider vcsutils.VcsProvider, hasInternetConnection bool) OutputWriter {
104-
if provider == vcsutils.BitbucketServer {
104+
if provider == vcsutils.BitbucketServer || provider == vcsutils.BitbucketCloud {
105105
return &SimplifiedOutput{MarkdownOutput{vcsProvider: provider, hasInternetConnection: hasInternetConnection}}
106106
}
107107
return &StandardOutput{MarkdownOutput{vcsProvider: provider, hasInternetConnection: hasInternetConnection}}

0 commit comments

Comments
 (0)