Skip to content

Commit 0af0131

Browse files
committed
[#4244] Feature/GitLab MR Comments
- Handle author and assocaited commits Signed-off-by: Harold Wanyama <hwanyama@contractor.linuxfoundation.org>
1 parent c515e62 commit 0af0131

6 files changed

Lines changed: 390 additions & 22 deletions

File tree

cla-backend-go/gitlab_api/client.go

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@ import (
1919
goGitLab "github.com/xanzy/go-gitlab"
2020
)
2121

22+
type GitLabClient interface {
23+
GetMergeRequestCommits(projectID int, mergeID int, opts *goGitLab.GetMergeRequestCommitsOptions) ([]*goGitLab.Commit, error)
24+
ListUsers(opts *goGitLab.ListUsersOptions) ([]*goGitLab.User, error)
25+
SetCommitStatus(projectID int, commitSHA string, opts *goGitLab.SetCommitStatusOptions) error
26+
}
27+
28+
// Client is the gitlab client
29+
type GitLabClientWrapper struct {
30+
gitlabClient *goGitLab.Client
31+
}
32+
2233
// OauthSuccessResponse is success response from Gitlab
2334
type OauthSuccessResponse struct {
2435
AccessToken string `json:"access_token"`
@@ -29,7 +40,7 @@ type OauthSuccessResponse struct {
2940
}
3041

3142
// NewGitlabOauthClient creates a new gitlab client from the given oauth info, authInfo is encrypted
32-
func NewGitlabOauthClient(authInfo string, gitLabApp *App) (*goGitLab.Client, error) {
43+
func NewGitlabOauthClient(authInfo string, gitLabApp *App) (GitLabClient, error) {
3344
if authInfo == "" {
3445
return nil, errors.New("unable to decrypt auth info - authentication info input is nil")
3546
}
@@ -47,7 +58,14 @@ func NewGitlabOauthClient(authInfo string, gitLabApp *App) (*goGitLab.Client, er
4758
}
4859

4960
log.Infof("creating oauth client with access token : %s", oauthResp.AccessToken)
50-
return goGitLab.NewOAuthClient(oauthResp.AccessToken)
61+
client, err := goGitLab.NewOAuthClient(oauthResp.AccessToken)
62+
if err != nil {
63+
return nil, err
64+
}
65+
66+
return &GitLabClientWrapper{
67+
gitlabClient: client,
68+
}, nil
5169
}
5270

5371
// NewGitlabOauthClientFromAccessToken creates a new gitlab client from the given access token
@@ -154,3 +172,30 @@ func decrypt(key, cipherText []byte) ([]byte, error) {
154172

155173
return cipherText, nil
156174
}
175+
176+
// GetMergeRequestCommits returns the commits for the given merge request
177+
func (c *GitLabClientWrapper) GetMergeRequestCommits(projectID int, mergeID int, opts *goGitLab.GetMergeRequestCommitsOptions) ([]*goGitLab.Commit, error) {
178+
commits, _, err := c.gitlabClient.MergeRequests.GetMergeRequestCommits(projectID, mergeID, opts)
179+
if err != nil {
180+
return nil, err
181+
}
182+
return commits, nil
183+
}
184+
185+
// ListUsers returns the list of users
186+
func (c *GitLabClientWrapper) ListUsers(opts *goGitLab.ListUsersOptions) ([]*goGitLab.User, error) {
187+
users, _, err := c.gitlabClient.Users.ListUsers(opts)
188+
if err != nil {
189+
return nil, err
190+
}
191+
return users, nil
192+
}
193+
194+
// SetCommitStatus sets the commit status
195+
func (c *GitLabClientWrapper) SetCommitStatus(projectID int, commitSHA string, opts *goGitLab.SetCommitStatusOptions) error {
196+
_, _, err := c.gitlabClient.Commits.SetCommitStatus(projectID, commitSHA, opts)
197+
if err != nil {
198+
return err
199+
}
200+
return nil
201+
}

cla-backend-go/gitlab_api/mocks/mock_client.go

Lines changed: 79 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cla-backend-go/gitlab_api/mr.go

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ import (
1414
"github.com/xanzy/go-gitlab"
1515
)
1616

17+
type UserCommitSummary struct {
18+
AuthorID int
19+
AuthorUsername string
20+
CommitSha string
21+
AuthorName string
22+
AuthorEmail string
23+
Authorized bool
24+
Affiliated bool
25+
}
26+
1727
// FetchMrInfo is responsible for fetching the MR info for given project
1828
func FetchMrInfo(client *gitlab.Client, projectID int, mergeID int) (*gitlab.MergeRequest, error) {
1929
m, _, err := client.MergeRequests.GetMergeRequest(projectID, mergeID, &gitlab.GetMergeRequestsOptions{})
@@ -24,15 +34,15 @@ func FetchMrInfo(client *gitlab.Client, projectID int, mergeID int) (*gitlab.Mer
2434
return m, nil
2535
}
2636

27-
func GetLatestCommit(client *gitlab.Client, projectID int, mergeID int) (*gitlab.Commit, error) {
37+
func GetLatestCommit(client GitLabClient, projectID int, mergeID int) (*gitlab.Commit, error) {
2838
f := logrus.Fields{
2939
"functionName": "gitlab_api.GetLatestCommit",
3040
"projectID": projectID,
3141
"mergeID": mergeID,
3242
}
3343

3444
log.WithFields(f).Debug("fetching latest commit...")
35-
commits, _, err := client.MergeRequests.GetMergeRequestCommits(projectID, mergeID, &gitlab.GetMergeRequestCommitsOptions{})
45+
commits, err := client.GetMergeRequestCommits(projectID, mergeID, &gitlab.GetMergeRequestCommitsOptions{})
3646
if err != nil {
3747
return nil, fmt.Errorf("fetching merge request commits : %d for project : %v failed : %v", mergeID, projectID, err)
3848
}
@@ -45,28 +55,26 @@ func GetLatestCommit(client *gitlab.Client, projectID int, mergeID int) (*gitlab
4555
}
4656

4757
// FetchMrParticipants is responsible to get unique mr participants
48-
func FetchMrParticipants(client *gitlab.Client, projectID int, mergeID int) ([]*gitlab.User, error) {
58+
func FetchMrParticipants(client GitLabClient, projectID int, mergeID int) ([]*UserCommitSummary, error) {
4959
f := logrus.Fields{
5060
"functionName": "gitlab_api.FetchMrParticipants",
5161
"projectID": projectID,
5262
"mergeID": mergeID,
5363
}
64+
65+
results := make([]*UserCommitSummary, 0)
66+
5467
log.WithFields(f).Debug("fetching mr participants...")
55-
commits, response, err := client.MergeRequests.GetMergeRequestCommits(projectID, mergeID, &gitlab.GetMergeRequestCommitsOptions{})
68+
commits, err := client.GetMergeRequestCommits(projectID, mergeID, &gitlab.GetMergeRequestCommitsOptions{})
5669
if err != nil {
5770
return nil, fmt.Errorf("fetching gitlab participants for project : %d and merge id : %d, failed : %v", projectID, mergeID, err)
5871
}
59-
if response.StatusCode != 200 {
60-
return nil, fmt.Errorf("fetching gitlab participants for project : %d and merge id : %d, failed with status code : %d", projectID, mergeID, response.StatusCode)
61-
}
6272

6373
if len(commits) == 0 {
6474
log.WithFields(f).Debugf("no commits found for project : %d and merge id : %d", projectID, mergeID)
65-
return nil, nil
75+
return results, nil
6676
}
6777

68-
var results []*gitlab.User
69-
7078
for _, commit := range commits {
7179
log.WithFields(f).Debugf("commit information: %v", commit)
7280
// The author is the person who originally wrote the code. The committer, on the other hand, is assumed to be
@@ -82,14 +90,16 @@ func FetchMrParticipants(client *gitlab.Client, projectID int, mergeID int) ([]*
8290
return nil, getUserErr
8391
}
8492

93+
user.CommitSha = commit.ShortID
94+
8595
results = append(results, user)
8696
}
8797

8898
return results, nil
8999
}
90100

91101
// SetCommitStatus is responsible for setting the MR status for commit sha
92-
func SetCommitStatus(client *gitlab.Client, projectID int, commitSha string, state gitlab.BuildStateValue, message string, targetURL string) error {
102+
func SetCommitStatus(client GitLabClient, projectID int, commitSha string, state gitlab.BuildStateValue, message string, targetURL string) error {
93103
f := logrus.Fields{
94104
"functionName": "gitlab_api.SetCommitStatus",
95105
"projectID": projectID,
@@ -110,7 +120,7 @@ func SetCommitStatus(client *gitlab.Client, projectID int, commitSha string, sta
110120
options.TargetURL = gitlab.String(targetURL)
111121
}
112122

113-
_, _, err := client.Commits.SetCommitStatus(projectID, commitSha, options)
123+
err := client.SetCommitStatus(projectID, commitSha, options)
114124
if err != nil {
115125
return fmt.Errorf("setting commit status for the sha : %s and project id : %d failed : %v", commitSha, projectID, err)
116126
}
@@ -161,23 +171,24 @@ func SetMrComment(client *gitlab.Client, projectID int, mergeID int, message str
161171
}
162172

163173
// getUser is responsible for fetching the user info for given user email
164-
func getUser(client *gitlab.Client, email, name *string) (*gitlab.User, error) {
174+
func getUser(client GitLabClient, email, name *string) (*UserCommitSummary, error) {
165175
f := logrus.Fields{
166176
"functionName": "gitlab_api.getUser",
167177
"email": *email,
168178
"name": *name,
169179
}
170180

171-
user := &gitlab.User{
172-
Email: *email,
173-
Name: *name,
181+
user := &UserCommitSummary{
182+
AuthorEmail: *email,
183+
AuthorName: *name,
174184
}
175185

176-
users, _, err := client.Users.ListUsers(&gitlab.ListUsersOptions{
186+
users, err := client.ListUsers(&gitlab.ListUsersOptions{
177187
Active: utils.Bool(true),
178188
Blocked: utils.Bool(false),
179189
Search: email,
180190
})
191+
181192
if err != nil {
182193
log.WithFields(f).Warnf("unable to find user for email : %s, error : %v", utils.StringValue(email), err)
183194
return nil, err
@@ -193,8 +204,8 @@ func getUser(client *gitlab.Client, email, name *string) (*gitlab.User, error) {
193204
for _, found := range users {
194205
if strings.EqualFold(found.Name, *name) {
195206
log.WithFields(f).Debugf("found matching user : %+v - updating GitLab username and ID", found)
196-
user.Username = found.Username
197-
user.ID = found.ID
207+
user.AuthorID = found.ID
208+
user.AuthorUsername = found.Username
198209
break
199210
}
200211
}

0 commit comments

Comments
 (0)