Skip to content

Commit

Permalink
enable gitlab pipeline mr protection (#3289)
Browse files Browse the repository at this point in the history
  • Loading branch information
makkalot authored Sep 16, 2021
1 parent 3ecebe5 commit bcb74e3
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 2 deletions.
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

0 comments on commit bcb74e3

Please sign in to comment.