Skip to content

Commit

Permalink
[communitybridge#4244] Feature/GitLab MR Comments
Browse files Browse the repository at this point in the history
- Handle author and assocaited commits

Signed-off-by: Harold Wanyama <hwanyama@contractor.linuxfoundation.org>
  • Loading branch information
nickmango committed Jul 5, 2024
1 parent c515e62 commit 0af0131
Show file tree
Hide file tree
Showing 6 changed files with 390 additions and 22 deletions.
49 changes: 47 additions & 2 deletions cla-backend-go/gitlab_api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ import (
goGitLab "github.com/xanzy/go-gitlab"
)

type GitLabClient interface {
GetMergeRequestCommits(projectID int, mergeID int, opts *goGitLab.GetMergeRequestCommitsOptions) ([]*goGitLab.Commit, error)
ListUsers(opts *goGitLab.ListUsersOptions) ([]*goGitLab.User, error)
SetCommitStatus(projectID int, commitSHA string, opts *goGitLab.SetCommitStatusOptions) error
}

// Client is the gitlab client
type GitLabClientWrapper struct {
gitlabClient *goGitLab.Client
}

// OauthSuccessResponse is success response from Gitlab
type OauthSuccessResponse struct {
AccessToken string `json:"access_token"`
Expand All @@ -29,7 +40,7 @@ type OauthSuccessResponse struct {
}

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

log.Infof("creating oauth client with access token : %s", oauthResp.AccessToken)
return goGitLab.NewOAuthClient(oauthResp.AccessToken)
client, err := goGitLab.NewOAuthClient(oauthResp.AccessToken)
if err != nil {
return nil, err
}

return &GitLabClientWrapper{
gitlabClient: client,
}, nil
}

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

return cipherText, nil
}

// GetMergeRequestCommits returns the commits for the given merge request
func (c *GitLabClientWrapper) GetMergeRequestCommits(projectID int, mergeID int, opts *goGitLab.GetMergeRequestCommitsOptions) ([]*goGitLab.Commit, error) {
commits, _, err := c.gitlabClient.MergeRequests.GetMergeRequestCommits(projectID, mergeID, opts)
if err != nil {
return nil, err
}
return commits, nil
}

// ListUsers returns the list of users
func (c *GitLabClientWrapper) ListUsers(opts *goGitLab.ListUsersOptions) ([]*goGitLab.User, error) {
users, _, err := c.gitlabClient.Users.ListUsers(opts)
if err != nil {
return nil, err
}
return users, nil
}

// SetCommitStatus sets the commit status
func (c *GitLabClientWrapper) SetCommitStatus(projectID int, commitSHA string, opts *goGitLab.SetCommitStatusOptions) error {
_, _, err := c.gitlabClient.Commits.SetCommitStatus(projectID, commitSHA, opts)
if err != nil {
return err
}
return nil
}
79 changes: 79 additions & 0 deletions cla-backend-go/gitlab_api/mocks/mock_client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 30 additions & 19 deletions cla-backend-go/gitlab_api/mr.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ import (
"github.com/xanzy/go-gitlab"
)

type UserCommitSummary struct {
AuthorID int
AuthorUsername string
CommitSha string
AuthorName string
AuthorEmail string
Authorized bool
Affiliated bool
}

// FetchMrInfo is responsible for fetching the MR info for given project
func FetchMrInfo(client *gitlab.Client, projectID int, mergeID int) (*gitlab.MergeRequest, error) {
m, _, err := client.MergeRequests.GetMergeRequest(projectID, mergeID, &gitlab.GetMergeRequestsOptions{})
Expand All @@ -24,15 +34,15 @@ func FetchMrInfo(client *gitlab.Client, projectID int, mergeID int) (*gitlab.Mer
return m, nil
}

func GetLatestCommit(client *gitlab.Client, projectID int, mergeID int) (*gitlab.Commit, error) {
func GetLatestCommit(client GitLabClient, projectID int, mergeID int) (*gitlab.Commit, error) {
f := logrus.Fields{
"functionName": "gitlab_api.GetLatestCommit",
"projectID": projectID,
"mergeID": mergeID,
}

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

// FetchMrParticipants is responsible to get unique mr participants
func FetchMrParticipants(client *gitlab.Client, projectID int, mergeID int) ([]*gitlab.User, error) {
func FetchMrParticipants(client GitLabClient, projectID int, mergeID int) ([]*UserCommitSummary, error) {
f := logrus.Fields{
"functionName": "gitlab_api.FetchMrParticipants",
"projectID": projectID,
"mergeID": mergeID,
}

results := make([]*UserCommitSummary, 0)

log.WithFields(f).Debug("fetching mr participants...")
commits, response, err := client.MergeRequests.GetMergeRequestCommits(projectID, mergeID, &gitlab.GetMergeRequestCommitsOptions{})
commits, err := client.GetMergeRequestCommits(projectID, mergeID, &gitlab.GetMergeRequestCommitsOptions{})
if err != nil {
return nil, fmt.Errorf("fetching gitlab participants for project : %d and merge id : %d, failed : %v", projectID, mergeID, err)
}
if response.StatusCode != 200 {
return nil, fmt.Errorf("fetching gitlab participants for project : %d and merge id : %d, failed with status code : %d", projectID, mergeID, response.StatusCode)
}

if len(commits) == 0 {
log.WithFields(f).Debugf("no commits found for project : %d and merge id : %d", projectID, mergeID)
return nil, nil
return results, nil
}

var results []*gitlab.User

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

user.CommitSha = commit.ShortID

results = append(results, user)
}

return results, nil
}

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

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

// getUser is responsible for fetching the user info for given user email
func getUser(client *gitlab.Client, email, name *string) (*gitlab.User, error) {
func getUser(client GitLabClient, email, name *string) (*UserCommitSummary, error) {
f := logrus.Fields{
"functionName": "gitlab_api.getUser",
"email": *email,
"name": *name,
}

user := &gitlab.User{
Email: *email,
Name: *name,
user := &UserCommitSummary{
AuthorEmail: *email,
AuthorName: *name,
}

users, _, err := client.Users.ListUsers(&gitlab.ListUsersOptions{
users, err := client.ListUsers(&gitlab.ListUsersOptions{
Active: utils.Bool(true),
Blocked: utils.Bool(false),
Search: email,
})

if err != nil {
log.WithFields(f).Warnf("unable to find user for email : %s, error : %v", utils.StringValue(email), err)
return nil, err
Expand All @@ -193,8 +204,8 @@ func getUser(client *gitlab.Client, email, name *string) (*gitlab.User, error) {
for _, found := range users {
if strings.EqualFold(found.Name, *name) {
log.WithFields(f).Debugf("found matching user : %+v - updating GitLab username and ID", found)
user.Username = found.Username
user.ID = found.ID
user.AuthorID = found.ID
user.AuthorUsername = found.Username
break
}
}
Expand Down
Loading

0 comments on commit 0af0131

Please sign in to comment.