Skip to content

Commit 2e6f8f9

Browse files
zakiskclaude
andcommitted
fix(gitlab): discard label removal events on merge requests
Label removal events on GitLab merge requests were incorrectly triggering pipeline runs. The hasOnlyLabelsChanged check used an OR condition that matched both additions and removals. Changed to compare current vs previous label count so only label additions are processed. Signed-off-by: Zaki Shaikh <zashaikh@redhat.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent fff1dac commit 2e6f8f9

2 files changed

Lines changed: 56 additions & 1 deletion

File tree

pkg/provider/gitlab/detect.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func (v *Provider) Detect(req *http.Request, payload string, logger *zap.Sugared
9090
func hasOnlyLabelsChanged(gitEvent *gitlab.MergeEvent) bool {
9191
changes := gitEvent.Changes
9292

93-
labelsChanged := len(changes.Labels.Previous) > 0 || len(changes.Labels.Current) > 0
93+
labelsChanged := isNewLabelAdded(changes.Labels.Previous, changes.Labels.Current)
9494

9595
// Only Labels can change — everything else must be zero or nil
9696
onlyUpdatedAtOrLabels := labelsChanged &&
@@ -108,3 +108,21 @@ func hasOnlyLabelsChanged(gitEvent *gitlab.MergeEvent) bool {
108108

109109
return onlyUpdatedAtOrLabels
110110
}
111+
112+
func isNewLabelAdded(previous, current []*gitlab.EventLabel) bool {
113+
newLabels := 0
114+
for _, label := range current {
115+
found := false
116+
for _, previousLabel := range previous {
117+
if label.Title == previousLabel.Title {
118+
found = true
119+
break
120+
}
121+
}
122+
if !found {
123+
newLabels++
124+
}
125+
}
126+
127+
return newLabels > 0
128+
}

pkg/provider/gitlab/detect_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ import (
1313

1414
const largeComment = "/Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s"
1515

16+
func mrEventWithChanges(sample thelp.TEvent, changesJSON string) string {
17+
base := sample.MREventAsJSON("update", "")
18+
idx := strings.LastIndex(base, "}")
19+
return base[:idx] + `,"changes": {` + changesJSON + `}}`
20+
}
21+
1622
func TestProviderDetect(t *testing.T) {
1723
sample := thelp.TEvent{
1824
Username: "foo",
@@ -173,6 +179,37 @@ func TestProviderDetect(t *testing.T) {
173179
isGL: true,
174180
processReq: true,
175181
},
182+
{
183+
name: "good/mergeRequest update Event with label addition",
184+
event: mrEventWithChanges(sample, `"labels": {"previous": [], "current": [{"id": 1, "title": "bug"}]}`),
185+
eventType: gitlab.EventTypeMergeRequest,
186+
isGL: true,
187+
processReq: true,
188+
},
189+
{
190+
name: "bad/mergeRequest update Event with label removal",
191+
event: mrEventWithChanges(sample, `"labels": {"previous": [{"id": 1, "title": "bug"}], "current": []}`),
192+
eventType: gitlab.EventTypeMergeRequest,
193+
isGL: true,
194+
processReq: false,
195+
wantReason: "this 'Merge Request' update event changes are not supported",
196+
},
197+
{
198+
name: "bad/mergeRequest update Event with label removal partial",
199+
event: mrEventWithChanges(sample, `"labels": {"previous": [{"id": 1, "title": "bug"}, {"id": 2, "title": "feature"}], "current": [{"id": 1, "title": "bug"}]}`),
200+
eventType: gitlab.EventTypeMergeRequest,
201+
isGL: true,
202+
processReq: false,
203+
wantReason: "this 'Merge Request' update event changes are not supported",
204+
},
205+
{
206+
name: "bad/mergeRequest update Event with label addition and description change",
207+
event: mrEventWithChanges(sample, `"labels": {"previous": [], "current": [{"id": 1, "title": "bug"}]}, "description": {"previous": "old", "current": "new"}`),
208+
eventType: gitlab.EventTypeMergeRequest,
209+
isGL: true,
210+
processReq: false,
211+
wantReason: "this 'Merge Request' update event changes are not supported",
212+
},
176213
{
177214
name: "good/commit comment /retest command",
178215
event: sample.CommitNoteEventAsJSON("/retest", "create", "null"),

0 commit comments

Comments
 (0)