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
99 changes: 97 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,27 @@ 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
GetProject(gitLabProjectID int, opts *goGitLab.GetProjectOptions) (*goGitLab.Project, error)
// EditProject(projectID int,)
ListGroupProjects(groupID int, opts *goGitLab.ListGroupProjectsOptions) ([]*goGitLab.Project, *goGitLab.Response, error)
ListGroupMembers(gid interface{}, opt *goGitLab.ListGroupMembersOptions) ([]*goGitLab.GroupMember, *goGitLab.Response, error)
CurrentUser() (*goGitLab.User, *goGitLab.Response, error)
ListUserProjects(user interface{}, opt *goGitLab.ListProjectsOptions) ([]*goGitLab.Project, *goGitLab.Response, error)
DeleteProjectHook(projectID, webhookID int) (*goGitLab.Response, error)
ListProjectHooks(projectID int, opts *goGitLab.ListProjectHooksOptions) ([]*goGitLab.ProjectHook, *goGitLab.Response, error)
AddProjectHook(projectID int, opts *goGitLab.AddProjectHookOptions) (*goGitLab.ProjectHook, *goGitLab.Response, error)
EditProjectHook(projectID, existingID int, opts *goGitLab.EditProjectHookOptions) (*goGitLab.ProjectHook, *goGitLab.Response, 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 +50,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 +68,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 +182,70 @@ func decrypt(key, cipherText []byte) ([]byte, error) {

return cipherText, nil
}

func (c *GitLabClientWrapper) ListGroupMembers(gid interface{}, opt *goGitLab.ListGroupMembersOptions) ([]*goGitLab.GroupMember, *goGitLab.Response, error) {
return c.gitlabClient.Groups.ListGroupMembers(gid, opt)
}

func (c *GitLabClientWrapper) GetProject(gitLabProjectID int, opts *goGitLab.GetProjectOptions) (*goGitLab.Project, error) {
project, _, err := c.gitlabClient.Projects.GetProject(gitLabProjectID, opts)
if err != nil {
return nil, err
}
return project, err
}

func (c *GitLabClientWrapper) CurrentUser() (*goGitLab.User, *goGitLab.Response, error) {
return c.gitlabClient.Users.CurrentUser()
}

// 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
}

func (c *GitLabClientWrapper) ListGroupProjects(groupID int, opts *goGitLab.ListGroupProjectsOptions) ([]*goGitLab.Project, *goGitLab.Response, error) {
return c.gitlabClient.Groups.ListGroupProjects(groupID, opts)
}

func (c *GitLabClientWrapper) ListUserProjects(user interface{}, opt *goGitLab.ListProjectsOptions) ([]*goGitLab.Project, *goGitLab.Response, error) {
return c.gitlabClient.Projects.ListUserProjects(user, opt)
}

func (c *GitLabClientWrapper) DeleteProjectHook(projectID, webhookID int) (*goGitLab.Response, error) {
return c.gitlabClient.Projects.DeleteProjectHook(projectID, webhookID)
}

func (c *GitLabClientWrapper) ListProjectHooks(projectID int, opts *goGitLab.ListProjectHooksOptions) ([]*goGitLab.ProjectHook, *goGitLab.Response, error) {
return c.gitlabClient.Projects.ListProjectHooks(projectID, opts)
}

func (c *GitLabClientWrapper) AddProjectHook(projectID int, opts *goGitLab.AddProjectHookOptions) (*goGitLab.ProjectHook, *goGitLab.Response, error) {
return c.gitlabClient.Projects.AddProjectHook(projectID, opts)
}

func (c *GitLabClientWrapper) EditProjectHook(projectID, existingID int, opts *goGitLab.EditProjectHookOptions) (*goGitLab.ProjectHook, *goGitLab.Response, error) {
return c.gitlabClient.Projects.EditProjectHook(projectID, existingID, opts)
}
12 changes: 6 additions & 6 deletions cla-backend-go/gitlab_api/client_groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func GetGroupByFullPath(ctx context.Context, client *goGitLab.Client, fullPath s
}

// GetGroupProjectListByGroupID returns a list of GitLab projects under the specified Organization
func GetGroupProjectListByGroupID(ctx context.Context, client *goGitLab.Client, groupID int) ([]*goGitLab.Project, error) {
func GetGroupProjectListByGroupID(ctx context.Context, client GitLabClient, groupID int) ([]*goGitLab.Project, error) {
f := logrus.Fields{
"functionName": "gitlab_api.client_groups.GetGroupProjectListByGroupID",
utils.XREQUESTID: ctx.Value(utils.XREQUESTID),
Expand All @@ -168,7 +168,7 @@ func GetGroupProjectListByGroupID(ctx context.Context, client *goGitLab.Client,
var projectList []*goGitLab.Project
for {
// https://docs.gitlab.com/ee/api/groups.html#list-a-groups-projects
projects, resp, listProjectsErr := client.Groups.ListGroupProjects(groupID, opts)
projects, resp, listProjectsErr := client.ListGroupProjects(groupID, opts)
if listProjectsErr != nil {
msg := fmt.Sprintf("unable to list projects, error: %+v", listProjectsErr)
log.WithFields(f).WithError(listProjectsErr).Warn(msg)
Expand All @@ -193,7 +193,7 @@ func GetGroupProjectListByGroupID(ctx context.Context, client *goGitLab.Client,
}

// ListGroupMembers lists the members of a given groupID
func ListGroupMembers(ctx context.Context, client *goGitLab.Client, groupID int) ([]*goGitLab.GroupMember, error) {
func ListGroupMembers(ctx context.Context, client GitLabClient, groupID int) ([]*goGitLab.GroupMember, error) {
f := logrus.Fields{
"functionName": "gitlab_api.client_groups.GetGroupMembers",
utils.XREQUESTID: ctx.Value(utils.XREQUESTID),
Expand All @@ -202,7 +202,7 @@ func ListGroupMembers(ctx context.Context, client *goGitLab.Client, groupID int)
log.WithFields(f).Debugf("fetching gitlab members for groupID: %d", groupID)

opts := &goGitLab.ListGroupMembersOptions{}
members, _, err := client.Groups.ListGroupMembers(groupID, opts)
members, _, err := client.ListGroupMembers(groupID, opts)
if err != nil {
log.WithFields(f).Debugf("unable to fetch members for gitlab GroupID : %d", groupID)
return nil, err
Expand All @@ -212,7 +212,7 @@ func ListGroupMembers(ctx context.Context, client *goGitLab.Client, groupID int)

// ListUserProjectGroups fetches the unique groups of a gitlab users groups,
// note: it doesn't list the projects/groups the user is member of ..., it's very limited
func ListUserProjectGroups(ctx context.Context, client *goGitLab.Client, userID int) ([]*UserGroup, error) {
func ListUserProjectGroups(ctx context.Context, client GitLabClient, userID int) ([]*UserGroup, error) {
f := logrus.Fields{
"functionName": "gitlab_api.client_groups.ListUserProjectGroups",
utils.XREQUESTID: ctx.Value(utils.XREQUESTID),
Expand All @@ -226,7 +226,7 @@ func ListUserProjectGroups(ctx context.Context, client *goGitLab.Client, userID
userGroupsMap := map[string]*UserGroup{}
for {
log.WithFields(f).Debugf("fetching projects for user id : %d with options : %v", userID, listOptions.ListOptions)
projects, resp, err := client.Projects.ListUserProjects(userID, listOptions)
projects, resp, err := client.ListUserProjects(userID, listOptions)
if err != nil {
msg := fmt.Sprintf("listing user : %d projects failed : %v", userID, err)
log.WithFields(f).Warn(msg)
Expand Down
15 changes: 5 additions & 10 deletions cla-backend-go/gitlab_api/client_projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,25 +85,20 @@ func getProjectListWithOptions(ctx context.Context, client *goGitLab.Client, opt
}

// GetProjectByID returns the GitLab project for the specified ID
func GetProjectByID(ctx context.Context, client *goGitLab.Client, gitLabProjectID int) (*goGitLab.Project, error) {
func GetProjectByID(ctx context.Context, client GitLabClient, gitLabProjectID int) (*goGitLab.Project, error) {
f := logrus.Fields{
"functionName": "gitlab.client.GetProjectByID",
utils.XREQUESTID: ctx.Value(utils.XREQUESTID),
"gitLabProjectID": gitLabProjectID,
}

// Query GitLab for repos - fetch the list of repositories available to the GitLab App
project, resp, getProjectErr := client.Projects.GetProject(gitLabProjectID, &goGitLab.GetProjectOptions{})
project, getProjectErr := client.GetProject(gitLabProjectID, &goGitLab.GetProjectOptions{})
if getProjectErr != nil {
msg := fmt.Sprintf("unable to get project by ID: %d, error: %+v", gitLabProjectID, getProjectErr)
log.WithFields(f).WithError(getProjectErr).Warn(msg)
return nil, errors.New(msg)
}
if resp.StatusCode < 200 || resp.StatusCode > 299 {
msg := fmt.Sprintf("unable to get project by ID: %d, status code: %d", gitLabProjectID, resp.StatusCode)
log.WithFields(f).WithError(getProjectErr).Warn(msg)
return nil, errors.New(msg)
}
if project == nil {
msg := fmt.Sprintf("unable to get project by ID: %d, project is empty", gitLabProjectID)
log.WithFields(f).WithError(getProjectErr).Warn(msg)
Expand All @@ -116,14 +111,14 @@ func GetProjectByID(ctx context.Context, client *goGitLab.Client, gitLabProjectI
// EnableMergePipelineProtection enables the pipeline protection on given project, by default it's
// turned off and when a new MR is raised users can merge requests bypassing the pipelines. With this
// setting gitlab disables the Merge button if any of the pipelines are failing
func EnableMergePipelineProtection(ctx context.Context, gitlabClient *goGitLab.Client, projectID int) error {
func EnableMergePipelineProtection(ctx context.Context, gitlabClient GitLabClient, projectID int) error {
f := logrus.Fields{
"functionName": "gitlab.client.EnableMergePipelineProtection",
utils.XREQUESTID: ctx.Value(utils.XREQUESTID),
"gitLabProjectID": projectID,
}

project, _, err := gitlabClient.Projects.GetProject(projectID, &goGitLab.GetProjectOptions{})
project, err := gitlabClient.GetProject(projectID, &goGitLab.GetProjectOptions{})
if err != nil {
return fmt.Errorf("fetching project failed : %v", err)
}
Expand All @@ -135,7 +130,7 @@ func EnableMergePipelineProtection(ctx context.Context, gitlabClient *goGitLab.C

project.OnlyAllowMergeIfPipelineSucceeds = true
log.WithFields(f).Debugf("Enabling Merge Pipeline protection")
_, _, err = gitlabClient.Projects.EditProject(projectID, &goGitLab.EditProjectOptions{
_, _, err = gitlabClient.EditProject(projectID, &goGitLab.EditProjectOptions{
OnlyAllowMergeIfPipelineSucceeds: goGitLab.Bool(true),
})

Expand Down
9 changes: 2 additions & 7 deletions cla-backend-go/gitlab_api/client_users.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ import (
)

// GetUserByName gets a gitlab user object by the given name
func GetUserByName(ctx context.Context, client *goGitLab.Client, name string) (*goGitLab.User, error) {
func GetUserByName(ctx context.Context, client GitLabClient, name string) (*goGitLab.User, error) {
f := logrus.Fields{
"functionName": "gitlab_api.client_users.GetUserByName",
utils.XREQUESTID: ctx.Value(utils.XREQUESTID),
"name": name,
}

users, resp, err := client.Users.ListUsers(&goGitLab.ListUsersOptions{
users, err := client.ListUsers(&goGitLab.ListUsersOptions{
ListOptions: goGitLab.ListOptions{
Page: 0,
PerPage: 10,
Expand All @@ -35,11 +35,6 @@ func GetUserByName(ctx context.Context, client *goGitLab.Client, name string) (*
log.WithFields(f).WithError(err).Warn(msg)
return nil, errors.New(msg)
}
if resp.StatusCode < 200 || resp.StatusCode > 299 {
msg := fmt.Sprintf("unable to get user using query: %s, status code: %d", name, resp.StatusCode)
log.WithFields(f).Warn(msg)
return nil, errors.New(msg)
}

if len(users) == 0 {
return nil, nil
Expand Down
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.

Loading
Loading