Skip to content

Commit cecac31

Browse files
committed
Enhance matchIssuesEvent function to support multiple label actions and add corresponding tests
1 parent 15e707c commit cecac31

File tree

2 files changed

+93
-18
lines changed

2 files changed

+93
-18
lines changed

modules/actions/workflows.go

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -367,21 +367,35 @@ func matchIssuesEvent(issuePayload *api.IssuePayload, evt *jobparser.Event) bool
367367
// Unsupported activity types:
368368
// deleted, transferred, pinned, unpinned, locked, unlocked
369369

370-
action := issuePayload.Action
371-
switch action {
370+
actions := []string{}
371+
switch issuePayload.Action {
372372
case api.HookIssueLabelUpdated:
373-
// Check if any labels were removed to determine if this should be "labeled" or "unlabeled"
374-
if len(issuePayload.RemovedLabels) > 0 {
375-
action = "unlabeled"
373+
// Check if both labels were added and removed to determine events to fire
374+
if len(issuePayload.Issue.Labels) > 0 && len(issuePayload.RemovedLabels) > 0 {
375+
// Both labeled and unlabeled events should be triggered
376+
actions = append(actions, "labeled", "unlabeled")
377+
} else if len(issuePayload.RemovedLabels) > 0 {
378+
// Only labels were removed
379+
actions = append(actions, "unlabeled")
376380
} else {
377-
action = "labeled"
381+
// Only labels were added
382+
actions = append(actions, "labeled")
378383
}
379384
case api.HookIssueLabelCleared:
380-
action = "unlabeled"
385+
actions = append(actions, "unlabeled")
386+
default:
387+
actions = append(actions, string(issuePayload.Action))
381388
}
389+
382390
for _, val := range vals {
383-
if glob.MustCompile(val, '/').Match(string(action)) {
384-
matchTimes++
391+
for _, action := range actions {
392+
if glob.MustCompile(val, '/').Match(action) {
393+
matchTimes++
394+
break
395+
}
396+
}
397+
// Once a match is found for this value, we can move to the next one
398+
if matchTimes > 0 {
385399
break
386400
}
387401
}

modules/actions/workflows_test.go

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,57 @@ func TestMatchIssuesEvent(t *testing.T) {
204204
expected: true,
205205
eventType: "unlabeled",
206206
},
207+
{
208+
desc: "Both adding and removing labels should trigger labeled event",
209+
payload: &api.IssuePayload{
210+
Action: api.HookIssueLabelUpdated,
211+
Issue: &api.Issue{
212+
Labels: []*api.Label{
213+
{ID: 789, Name: "new-label"},
214+
},
215+
},
216+
RemovedLabels: []*api.Label{
217+
{ID: 123, Name: "deleted-label"},
218+
},
219+
},
220+
yamlOn: "on:\n issues:\n types: [labeled]",
221+
expected: true,
222+
eventType: "labeled",
223+
},
224+
{
225+
desc: "Both adding and removing labels should trigger unlabeled event",
226+
payload: &api.IssuePayload{
227+
Action: api.HookIssueLabelUpdated,
228+
Issue: &api.Issue{
229+
Labels: []*api.Label{
230+
{ID: 789, Name: "new-label"},
231+
},
232+
},
233+
RemovedLabels: []*api.Label{
234+
{ID: 123, Name: "deleted-label"},
235+
},
236+
},
237+
yamlOn: "on:\n issues:\n types: [unlabeled]",
238+
expected: true,
239+
eventType: "unlabeled",
240+
},
241+
{
242+
desc: "Both adding and removing labels should trigger both events",
243+
payload: &api.IssuePayload{
244+
Action: api.HookIssueLabelUpdated,
245+
Issue: &api.Issue{
246+
Labels: []*api.Label{
247+
{ID: 789, Name: "new-label"},
248+
},
249+
},
250+
RemovedLabels: []*api.Label{
251+
{ID: 123, Name: "deleted-label"},
252+
},
253+
},
254+
yamlOn: "on:\n issues:\n types: [labeled, unlabeled]",
255+
expected: true,
256+
eventType: "multiple",
257+
},
207258
}
208259

209260
for _, tc := range testCases {
@@ -215,19 +266,29 @@ func TestMatchIssuesEvent(t *testing.T) {
215266
// Test if the event matches as expected
216267
assert.Equal(t, tc.expected, matchIssuesEvent(tc.payload, evts[0]))
217268

218-
// For extra validation, use a direct call to test the actual mapping
219-
action := tc.payload.Action
220-
switch action {
269+
// For extra validation, check that action mapping works correctly
270+
if tc.eventType == "multiple" {
271+
// Skip direct action mapping validation for multiple events case
272+
// as one action can map to multiple event types
273+
return
274+
}
275+
276+
// Determine expected action for single event case
277+
var expectedAction string
278+
switch tc.payload.Action {
221279
case api.HookIssueLabelUpdated:
222-
if len(tc.payload.RemovedLabels) > 0 {
223-
action = "unlabeled"
224-
} else {
225-
action = "labeled"
280+
if tc.eventType == "labeled" {
281+
expectedAction = "labeled"
282+
} else if tc.eventType == "unlabeled" {
283+
expectedAction = "unlabeled"
226284
}
227285
case api.HookIssueLabelCleared:
228-
action = "unlabeled"
286+
expectedAction = "unlabeled"
287+
default:
288+
expectedAction = string(tc.payload.Action)
229289
}
230-
assert.Equal(t, tc.eventType, string(action), "Event type should match expected")
290+
291+
assert.Equal(t, tc.eventType, expectedAction, "Event type should match expected")
231292
})
232293
}
233294
}

0 commit comments

Comments
 (0)