Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#4244] Feature/GitLab MR Comments #4375

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading