Skip to content

Commit 6a0a3cd

Browse files
fix(gitlab): trigger PipelineRun only on label change
Before this patch pipeline was triggered on any merge request update, regardless of what changed such as title, description or assigne changes With the current change, pipeline will be triggered only when labels are added or removed Signed-off-by: PuneetPunamiya <[email protected]>
1 parent 9e37185 commit 6a0a3cd

File tree

3 files changed

+123
-0
lines changed

3 files changed

+123
-0
lines changed

pkg/provider/gitlab/detect.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ func (v *Provider) Detect(req *http.Request, payload string, logger *zap.Sugared
3838

3939
switch gitEvent := eventInt.(type) {
4040
case *gitlab.MergeEvent:
41+
if gitEvent.ObjectAttributes.Action == "update" && gitEvent.ObjectAttributes.OldRev == "" {
42+
if !hasOnlyLabelsChanged(gitEvent) {
43+
return setLoggerAndProceed(false, "it's a merge event but has other changes", nil)
44+
}
45+
}
46+
4147
if provider.Valid(gitEvent.ObjectAttributes.Action, []string{"open", "reopen", "update"}) {
4248
return setLoggerAndProceed(true, "", nil)
4349
}
@@ -76,3 +82,26 @@ func (v *Provider) Detect(req *http.Request, payload string, logger *zap.Sugared
7682
return setLoggerAndProceed(false, "", fmt.Errorf("gitlab: event \"%s\" is not supported", event))
7783
}
7884
}
85+
86+
func hasOnlyLabelsChanged(gitEvent *gitlab.MergeEvent) bool {
87+
changes := gitEvent.Changes
88+
89+
labelsChanged := len(changes.Labels.Previous) > 0 || len(changes.Labels.Current) > 0
90+
91+
// Only Labels can change — everything else must be zero or nil
92+
onlyUpdatedAtOrLabels := labelsChanged &&
93+
changes.Assignees.Previous == nil && changes.Assignees.Current == nil &&
94+
changes.Reviewers.Previous == nil && changes.Reviewers.Current == nil &&
95+
changes.Description.Previous == "" && changes.Description.Current == "" &&
96+
!changes.Draft.Previous && !changes.Draft.Current &&
97+
changes.MergeStatus.Previous == "" && changes.MergeStatus.Current == "" &&
98+
changes.MilestoneID.Previous == 0 && changes.MilestoneID.Current == 0 &&
99+
changes.SourceBranch.Previous == "" && changes.SourceBranch.Current == "" &&
100+
changes.SourceProjectID.Previous == 0 && changes.SourceProjectID.Current == 0 &&
101+
changes.StateID.Previous == 0 && changes.StateID.Current == 0 &&
102+
changes.TargetBranch.Previous == "" && changes.TargetBranch.Current == "" &&
103+
changes.TargetProjectID.Previous == 0 && changes.TargetProjectID.Current == 0 &&
104+
changes.Title.Previous == "" && changes.Title.Current == ""
105+
106+
return onlyUpdatedAtOrLabels
107+
}

pkg/provider/gitlab/detect_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,20 @@ func TestProvider_Detect(t *testing.T) {
7272
isGL: true,
7373
processReq: true,
7474
},
75+
{
76+
name: "good/mergeRequest update Event with title",
77+
event: sample.MREventAsJSON("update", `"title": "test"`),
78+
eventType: gitlab.EventTypeMergeRequest,
79+
isGL: true,
80+
processReq: false,
81+
},
82+
{
83+
name: "good/mergeRequest update Event with description",
84+
event: sample.MREventAsJSON("update", `"description": "test pac"`),
85+
eventType: gitlab.EventTypeMergeRequest,
86+
isGL: true,
87+
processReq: false,
88+
},
7589
{
7690
name: "good/note event",
7791
event: sample.NoteEventAsJSON("abc"),

test/gitlab_merge_request_test.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,86 @@ func TestGitlabDisableCommentsOnMR(t *testing.T) {
616616
assert.Equal(t, 2, successCommentsPost)
617617
}
618618

619+
func TestGitlabMergeRequestOnUpdateAtAndLabelChange(t *testing.T) {
620+
targetNS := names.SimpleNameGenerator.RestrictLengthWithRandomSuffix("pac-e2e-ns")
621+
ctx := context.Background()
622+
runcnx, opts, glprovider, err := tgitlab.Setup(ctx)
623+
assert.NilError(t, err)
624+
ctx, err = cctx.GetControllerCtxInfo(ctx, runcnx)
625+
assert.NilError(t, err)
626+
runcnx.Clients.Log.Info("Testing with Gitlab")
627+
628+
projectinfo, resp, err := glprovider.Client().Projects.GetProject(opts.ProjectID, nil)
629+
assert.NilError(t, err)
630+
if resp != nil && resp.StatusCode == http.StatusNotFound {
631+
t.Errorf("Repository %s not found in %s", opts.Organization, opts.Repo)
632+
}
633+
634+
err = tgitlab.CreateCRD(ctx, projectinfo, runcnx, opts, targetNS, nil)
635+
assert.NilError(t, err)
636+
637+
entries, err := payload.GetEntries(map[string]string{
638+
".tekton/pipelinerun.yaml": "testdata/pipelinerun.yaml",
639+
".tekton/pipelinerun-clone.yaml": "testdata/pipelinerun-clone.yaml",
640+
}, targetNS, projectinfo.DefaultBranch,
641+
triggertype.PullRequest.String(), map[string]string{})
642+
assert.NilError(t, err)
643+
644+
targetRefName := names.SimpleNameGenerator.RestrictLengthWithRandomSuffix("pac-e2e-test")
645+
646+
gitCloneURL, err := scm.MakeGitCloneURL(projectinfo.WebURL, opts.UserName, opts.Password)
647+
assert.NilError(t, err)
648+
commitTitle := "Committing files from test on " + targetRefName
649+
scmOpts := &scm.Opts{
650+
GitURL: gitCloneURL,
651+
CommitTitle: commitTitle,
652+
Log: runcnx.Clients.Log,
653+
WebURL: projectinfo.WebURL,
654+
TargetRefName: targetRefName,
655+
BaseRefName: projectinfo.DefaultBranch,
656+
}
657+
_ = scm.PushFilesToRefGit(t, scmOpts, entries)
658+
659+
runcnx.Clients.Log.Infof("Branch %s has been created and pushed with files", targetRefName)
660+
mrTitle := "TestMergeRequest - " + targetRefName
661+
mrID, err := tgitlab.CreateMR(glprovider.Client(), opts.ProjectID, targetRefName, projectinfo.DefaultBranch, mrTitle)
662+
assert.NilError(t, err)
663+
runcnx.Clients.Log.Infof("MergeRequest %s/-/merge_requests/%d has been created", projectinfo.WebURL, mrID)
664+
defer tgitlab.TearDown(ctx, t, runcnx, glprovider, mrID, targetRefName, targetNS, opts.ProjectID)
665+
666+
// Send another Push to make an update and make sure we react to it
667+
entries, err = payload.GetEntries(map[string]string{
668+
"hello-world.yaml": "testdata/pipelinerun.yaml",
669+
}, targetNS, projectinfo.DefaultBranch,
670+
triggertype.PullRequest.String(), map[string]string{})
671+
assert.NilError(t, err)
672+
scmOpts.BaseRefName = targetRefName
673+
_ = scm.PushFilesToRefGit(t, scmOpts, entries)
674+
675+
sopt := twait.SuccessOpt{
676+
Title: commitTitle,
677+
OnEvent: "Merge Request",
678+
TargetNS: targetNS,
679+
NumberofPRMatch: 4,
680+
SHA: "",
681+
}
682+
twait.Succeeded(ctx, t, runcnx, opts, sopt)
683+
prsNew, err := runcnx.Clients.Tekton.TektonV1().PipelineRuns(targetNS).List(ctx, metav1.ListOptions{})
684+
assert.NilError(t, err)
685+
assert.Assert(t, len(prsNew.Items) == 4)
686+
687+
for i := 0; i < len(prsNew.Items); i++ {
688+
assert.Equal(t, "Merge Request", prsNew.Items[i].Annotations[keys.EventType])
689+
}
690+
691+
runcnx.Clients.Log.Infof("Changing Title on MergeRequest %s/-/merge_requests/%d", projectinfo.WebURL, mrID)
692+
_, _, err = glprovider.Client().MergeRequests.UpdateMergeRequest(opts.ProjectID, mrID, &clientGitlab.UpdateMergeRequestOptions{
693+
Title: clientGitlab.Ptr("test"),
694+
})
695+
assert.NilError(t, err)
696+
assert.Assert(t, len(prsNew.Items) == 4)
697+
}
698+
619699
// Local Variables:
620700
// compile-command: "go test -tags=e2e -v -run ^TestGitlabMergeRequest$"
621701
// End:

0 commit comments

Comments
 (0)