github.com/argoproj/argo-cd/v3@v3.2.1/applicationset/services/pull_request/bitbucket_server.go (about) 1 package pull_request 2 3 import ( 4 "context" 5 "fmt" 6 "net/http" 7 8 bitbucketv1 "github.com/gfleury/go-bitbucket-v1" 9 log "github.com/sirupsen/logrus" 10 11 "github.com/argoproj/argo-cd/v3/applicationset/services" 12 ) 13 14 type BitbucketService struct { 15 client *bitbucketv1.APIClient 16 projectKey string 17 repositorySlug string 18 // Not supported for PRs by Bitbucket Server 19 // labels []string 20 } 21 22 var _ PullRequestService = (*BitbucketService)(nil) 23 24 func NewBitbucketServiceBasicAuth(ctx context.Context, username, password, url, projectKey, repositorySlug string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) { 25 bitbucketConfig := bitbucketv1.NewConfiguration(url) 26 // Avoid the XSRF check 27 bitbucketConfig.AddDefaultHeader("x-atlassian-token", "no-check") 28 bitbucketConfig.AddDefaultHeader("x-requested-with", "XMLHttpRequest") 29 30 ctx = context.WithValue(ctx, bitbucketv1.ContextBasicAuth, bitbucketv1.BasicAuth{ 31 UserName: username, 32 Password: password, 33 }) 34 return newBitbucketService(ctx, bitbucketConfig, projectKey, repositorySlug, scmRootCAPath, insecure, caCerts) 35 } 36 37 func NewBitbucketServiceBearerToken(ctx context.Context, bearerToken, url, projectKey, repositorySlug string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) { 38 bitbucketConfig := bitbucketv1.NewConfiguration(url) 39 // Avoid the XSRF check 40 bitbucketConfig.AddDefaultHeader("x-atlassian-token", "no-check") 41 bitbucketConfig.AddDefaultHeader("x-requested-with", "XMLHttpRequest") 42 43 ctx = context.WithValue(ctx, bitbucketv1.ContextAccessToken, bearerToken) 44 return newBitbucketService(ctx, bitbucketConfig, projectKey, repositorySlug, scmRootCAPath, insecure, caCerts) 45 } 46 47 func NewBitbucketServiceNoAuth(ctx context.Context, url, projectKey, repositorySlug string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) { 48 return newBitbucketService(ctx, bitbucketv1.NewConfiguration(url), projectKey, repositorySlug, scmRootCAPath, insecure, caCerts) 49 } 50 51 func newBitbucketService(ctx context.Context, bitbucketConfig *bitbucketv1.Configuration, projectKey, repositorySlug string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) { 52 bbClient := services.SetupBitbucketClient(ctx, bitbucketConfig, scmRootCAPath, insecure, caCerts) 53 54 return &BitbucketService{ 55 client: bbClient, 56 projectKey: projectKey, 57 repositorySlug: repositorySlug, 58 }, nil 59 } 60 61 func (b *BitbucketService) List(_ context.Context) ([]*PullRequest, error) { 62 paged := map[string]any{ 63 "limit": 100, 64 } 65 66 pullRequests := []*PullRequest{} 67 for { 68 response, err := b.client.DefaultApi.GetPullRequestsPage(b.projectKey, b.repositorySlug, paged) 69 if err != nil { 70 if response != nil && response.Response != nil && response.StatusCode == http.StatusNotFound { 71 // return a custom error indicating that the repository is not found, 72 // but also return the empty result since the decision to continue or not in this case is made by the caller 73 return pullRequests, NewRepositoryNotFoundError(err) 74 } 75 return nil, fmt.Errorf("error listing pull requests for %s/%s: %w", b.projectKey, b.repositorySlug, err) 76 } 77 pulls, err := bitbucketv1.GetPullRequestsResponse(response) 78 if err != nil { 79 log.Errorf("error parsing pull request response '%v'", response.Values) 80 return nil, fmt.Errorf("error parsing pull request response for %s/%s: %w", b.projectKey, b.repositorySlug, err) 81 } 82 83 for _, pull := range pulls { 84 pullRequests = append(pullRequests, &PullRequest{ 85 Number: pull.ID, 86 Title: pull.Title, 87 Branch: pull.FromRef.DisplayID, // ID: refs/heads/main DisplayID: main 88 TargetBranch: pull.ToRef.DisplayID, 89 HeadSHA: pull.FromRef.LatestCommit, // This is not defined in the official docs, but works in practice 90 Labels: []string{}, // Not supported by library 91 Author: pull.Author.User.Name, 92 }) 93 } 94 95 hasNextPage, nextPageStart := bitbucketv1.HasNextPage(response) 96 if !hasNextPage { 97 break 98 } 99 paged["start"] = nextPageStart 100 } 101 return pullRequests, nil 102 }