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

enable gitlab pipeline mr protection #3289

Merged
Merged
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
69 changes: 69 additions & 0 deletions cla-backend-go/cmd/gitlab/gitlaborgevents/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright The Linux Foundation and each contributor to CommunityBridge.
// SPDX-License-Identifier: MIT

package main

import (
"encoding/json"
"os"

"github.com/aws/aws-lambda-go/events"
log "github.com/communitybridge/easycla/cla-backend-go/logging"
)

// This function is useful for generating dynamodb events for GitlabOrg testing, the output of this function is used as
// ./bin/dynamo-events-lambda-mac {OUTPUT_OF_THIS_FUNCTION}
func main() {
// authInfo needed for creating the gitlab client
authInfo := os.Getenv("GITLAB_AUTH_INFO")

event := events.DynamoDBEvent{
Records: []events.DynamoDBEventRecord{
{
EventSourceArn: "aws:dynamodb/cla-dev-gitlab-orgs",
EventName: "MODIFY",
EventSource: "aws:dynamodb",
Change: events.DynamoDBStreamRecord{
OldImage: map[string]events.DynamoDBAttributeValue{
"organization_id": events.NewStringAttribute("4ace6f9f-0518-4621-ae86-d0dacc75af83"),
"organization_full_path": events.NewStringAttribute("penguinsoft"),
"organization_sfid": events.NewStringAttribute("a092M00001If9uZQAR"),
"auto_enabled_cla_group_id": events.NewStringAttribute("40af3652-e8bf-489d-a917-cb2214a89640"),
"external_gitlab_group_id": events.NewNumberAttribute("12700028"),
"auth_state": events.NewStringAttribute("18eb90d1-8c36-4962-ba91-e264ccbcab3a"),
"organization_url": events.NewStringAttribute("https://gitlab.com/groups/penguinsoft"),
"auth_info": events.NewStringAttribute(authInfo),
"organization_name_lower": events.NewStringAttribute("penguinsoft"),
"project_sfid": events.NewStringAttribute("a092M00001If9uZQAR"),
"organization_name": events.NewStringAttribute("penguinsoft"),
"enabled": events.NewBooleanAttribute(false),
"auto_enabled": events.NewBooleanAttribute(false),
"branch_protection_enabled": events.NewBooleanAttribute(false),
},
NewImage: map[string]events.DynamoDBAttributeValue{
"organization_id": events.NewStringAttribute("4ace6f9f-0518-4621-ae86-d0dacc75af83"),
"organization_full_path": events.NewStringAttribute("penguinsoft"),
"organization_sfid": events.NewStringAttribute("a092M00001If9uZQAR"),
"auto_enabled_cla_group_id": events.NewStringAttribute("40af3652-e8bf-489d-a917-cb2214a89640"),
"external_gitlab_group_id": events.NewNumberAttribute("12700028"),
"auth_state": events.NewStringAttribute("18eb90d1-8c36-4962-ba91-e264ccbcab3a"),
"organization_url": events.NewStringAttribute("https://gitlab.com/groups/penguinsoft"),
"auth_info": events.NewStringAttribute(authInfo),
"organization_name_lower": events.NewStringAttribute("penguinsoft"),
"project_sfid": events.NewStringAttribute("a092M00001If9uZQAR"),
"organization_name": events.NewStringAttribute("penguinsoft"),
"enabled": events.NewBooleanAttribute(true),
"auto_enabled": events.NewBooleanAttribute(false),
"branch_protection_enabled": events.NewBooleanAttribute(true),
},
}},
},
}

b, err := json.Marshal(event)
if err != nil {
log.Fatalf("marshall : %v", err)
}

log.Println(string(b))
}
39 changes: 39 additions & 0 deletions cla-backend-go/cmd/gitlab/project_settings/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright The Linux Foundation and each contributor to CommunityBridge.
// SPDX-License-Identifier: MIT

package main

import (
"context"
"flag"
gitlab_api "github.com/communitybridge/easycla/cla-backend-go/gitlab_api"
log "github.com/communitybridge/easycla/cla-backend-go/logging"
"github.com/xanzy/go-gitlab"
"os"
)

var projectID = flag.Int("project", 0, "gitlab project id")

func main() {
flag.Parse()

if *projectID == 0 {
log.Fatalf("gitlab project id is missing")
}

accessToken := os.Getenv("GITLAB_ACCESS_TOKEN")
if accessToken == "" {
log.Fatalf("GITLAB_ACCESS_TOKEN is required")
}

gitlabClient, err := gitlab.NewOAuthClient(accessToken)
if err != nil {
log.Fatalf("creating client failed : %v", err)
}

if err := gitlab_api.EnableMergePipelineProtection(context.Background(), gitlabClient, *projectID); err != nil {
log.Fatalf("enabling merge pipeline protection failed : %v", err)
}

log.Println("merge pipeline protection enabled successfully")
}
55 changes: 55 additions & 0 deletions cla-backend-go/cmd/gitlab/repoevents/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright The Linux Foundation and each contributor to CommunityBridge.
// SPDX-License-Identifier: MIT

package main

import (
"encoding/json"

"github.com/aws/aws-lambda-go/events"
log "github.com/communitybridge/easycla/cla-backend-go/logging"
)

// This function is useful for generating dynamodb events for Repository testing, the output of this function is used as
// ./bin/dynamo-events-lambda-mac {OUTPUT_OF_THIS_FUNCTION}
func main() {
event := events.DynamoDBEvent{
Records: []events.DynamoDBEventRecord{
{
EventSourceArn: "aws:dynamodb/cla-dev-repositories",
EventName: "MODIFY",
EventSource: "aws:dynamodb",
Change: events.DynamoDBStreamRecord{
OldImage: map[string]events.DynamoDBAttributeValue{
"repository_id": events.NewStringAttribute("1fa3de39-8274-4750-ba7c-242d5d659dd1"),
"repository_name": events.NewStringAttribute("easycla-gitlab-test"),
"repository_organization_name": events.NewStringAttribute("penguinsoft"),
"repository_project_id": events.NewStringAttribute("40af3652-e8bf-489d-a917-cb2214a89640"),
"repository_sfdc_id": events.NewStringAttribute("a092M00001If9uZQAR"),
"project_sfid": events.NewStringAttribute("a092M00001If9uZQAR"),
"repository_external_id": events.NewNumberAttribute("28893091"),
"repository_type": events.NewStringAttribute("gitlab"),
"enabled": events.NewBooleanAttribute(false),
},
NewImage: map[string]events.DynamoDBAttributeValue{
"repository_id": events.NewStringAttribute("1fa3de39-8274-4750-ba7c-242d5d659dd1"),
"repository_name": events.NewStringAttribute("easycla-gitlab-test"),
"repository_organization_name": events.NewStringAttribute("penguinsoft"),
"repository_project_id": events.NewStringAttribute("40af3652-e8bf-489d-a917-cb2214a89640"),
"repository_sfdc_id": events.NewStringAttribute("a092M00001If9uZQAR"),
"project_sfid": events.NewStringAttribute("a092M00001If9uZQAR"),
"repository_external_id": events.NewNumberAttribute("28893091"),
"repository_type": events.NewStringAttribute("gitlab"),
"enabled": events.NewBooleanAttribute(true),
},
}},
},
}

b, err := json.Marshal(event)
if err != nil {
log.Fatalf("marshall : %v", err)
}

log.Println(string(b))
}
32 changes: 32 additions & 0 deletions cla-backend-go/gitlab_api/client_projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,35 @@ func GetProjectByID(ctx context.Context, client *goGitLab.Client, gitLabProjectI

return project, nil
}

// 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 {
f := logrus.Fields{
"functionName": "gitlab.client.EnableMergePipelineProtection",
utils.XREQUESTID: ctx.Value(utils.XREQUESTID),
"gitLabProjectID": projectID,
}

project, _, err := gitlabClient.Projects.GetProject(projectID, &goGitLab.GetProjectOptions{})
if err != nil {
return fmt.Errorf("fetching project failed : %v", err)
}

log.WithFields(f).Debugf("Merge if Pipeline is succeeds flag enabled : %v", project.OnlyAllowMergeIfPipelineSucceeds)
if project.OnlyAllowMergeIfPipelineSucceeds {
return nil
}

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

if err != nil {
return fmt.Errorf("editing project : %d failed : %v", projectID, err)
}
return nil
}
1 change: 1 addition & 0 deletions cla-backend-go/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUr
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down
9 changes: 7 additions & 2 deletions cla-backend-go/v2/dynamo_events/gitlab_webhooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ func (s *service) GitLabRepoAddedWebhookEventHandler(event events.DynamoDBEventR
if err := gitlab_api.SetWebHook(gitLabClient, conf.Gitlab.WebHookURI, repositoryExternalIDInt, gitlabOrg.AuthState); err != nil {
log.WithFields(f).Errorf("adding gitlab webhook failed : %v", err)
}

log.WithFields(f).Debugf("gitlab webhhok added succesfully for repository")
return nil

log.WithFields(f).Debugf("enabling gitlab pipeline protection if not alreasy")
return gitlab_api.EnableMergePipelineProtection(ctx, gitLabClient, repositoryExternalIDInt)
}

func (s *service) GitlabRepoModifiedWebhookEventHandler(event events.DynamoDBEventRecord) error {
Expand Down Expand Up @@ -140,6 +141,10 @@ func (s *service) GitlabRepoModifiedWebhookEventHandler(event events.DynamoDBEve
if err := gitlab_api.SetWebHook(gitLabClient, conf.Gitlab.WebHookURI, repositoryExternalIDInt, gitlabOrg.AuthState); err != nil {
log.WithFields(f).Errorf("adding gitlab webhook failed : %v", err)
}
log.WithFields(f).Debugf("enabling gitlab pipeline protection if not alreasy")
if err := gitlab_api.EnableMergePipelineProtection(ctx, gitLabClient, repositoryExternalIDInt); err != nil {
return err
}
} else {
if err := gitlab_api.RemoveWebHook(gitLabClient, conf.Gitlab.WebHookURI, repositoryExternalIDInt); err != nil {
log.WithFields(f).Errorf("removing gitlab webhook failed : %v", err)
Expand Down