github.com/argoproj/argo-cd/v3@v3.2.1/applicationset/services/pull_request/gitlab.go (about) 1 package pull_request 2 3 import ( 4 "context" 5 "fmt" 6 "net/http" 7 "os" 8 9 "github.com/hashicorp/go-retryablehttp" 10 gitlab "gitlab.com/gitlab-org/api/client-go" 11 12 "github.com/argoproj/argo-cd/v3/applicationset/utils" 13 ) 14 15 type GitLabService struct { 16 client *gitlab.Client 17 project string 18 labels []string 19 pullRequestState string 20 } 21 22 var _ PullRequestService = (*GitLabService)(nil) 23 24 func NewGitLabService(token, url, project string, labels []string, pullRequestState string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) { 25 var clientOptionFns []gitlab.ClientOptionFunc 26 27 // Set a custom Gitlab base URL if one is provided 28 if url != "" { 29 clientOptionFns = append(clientOptionFns, gitlab.WithBaseURL(url)) 30 } 31 32 if token == "" { 33 token = os.Getenv("GITLAB_TOKEN") 34 } 35 36 tr := http.DefaultTransport.(*http.Transport).Clone() 37 tr.TLSClientConfig = utils.GetTlsConfig(scmRootCAPath, insecure, caCerts) 38 39 retryClient := retryablehttp.NewClient() 40 retryClient.HTTPClient.Transport = tr 41 42 clientOptionFns = append(clientOptionFns, gitlab.WithHTTPClient(retryClient.HTTPClient)) 43 44 client, err := gitlab.NewClient(token, clientOptionFns...) 45 if err != nil { 46 return nil, fmt.Errorf("error creating Gitlab client: %w", err) 47 } 48 49 return &GitLabService{ 50 client: client, 51 project: project, 52 labels: labels, 53 pullRequestState: pullRequestState, 54 }, nil 55 } 56 57 func (g *GitLabService) List(ctx context.Context) ([]*PullRequest, error) { 58 // Filter the merge requests on labels, if they are specified. 59 var labels *gitlab.LabelOptions 60 if len(g.labels) > 0 { 61 var labelsList gitlab.LabelOptions = g.labels 62 labels = &labelsList 63 } 64 opts := &gitlab.ListProjectMergeRequestsOptions{ 65 ListOptions: gitlab.ListOptions{ 66 PerPage: 100, 67 }, 68 Labels: labels, 69 } 70 71 if g.pullRequestState != "" { 72 opts.State = &g.pullRequestState 73 } 74 75 pullRequests := []*PullRequest{} 76 for { 77 mrs, resp, err := g.client.MergeRequests.ListProjectMergeRequests(g.project, opts, gitlab.WithContext(ctx)) 78 if err != nil { 79 if resp != nil && resp.StatusCode == http.StatusNotFound { 80 // return a custom error indicating that the repository is not found, 81 // but also returning the empty result since the decision to continue or not in this case is made by the caller 82 return pullRequests, NewRepositoryNotFoundError(err) 83 } 84 return nil, fmt.Errorf("error listing merge requests for project '%s': %w", g.project, err) 85 } 86 for _, mr := range mrs { 87 pullRequests = append(pullRequests, &PullRequest{ 88 Number: mr.IID, 89 Title: mr.Title, 90 Branch: mr.SourceBranch, 91 TargetBranch: mr.TargetBranch, 92 HeadSHA: mr.SHA, 93 Labels: mr.Labels, 94 Author: mr.Author.Username, 95 }) 96 } 97 if resp.NextPage == 0 { 98 break 99 } 100 opts.Page = resp.NextPage 101 } 102 return pullRequests, nil 103 }