buildLabelCommandCondition creates a condition that checks whether the triggering label matches one of the configured label-command names. For non-label events (e.g. workflow_dispatch and any other events in LabelCommandOtherEvents), the condition passes unconditionally so that manual runs and other
(labelNames []string, labelCommandEvents []string, hasOtherEvents bool)
| 36 | // workflow_dispatch and any other events in LabelCommandOtherEvents), the condition |
| 37 | // passes unconditionally so that manual runs and other triggers still work. |
| 38 | func buildLabelCommandCondition(labelNames []string, labelCommandEvents []string, hasOtherEvents bool) (ConditionNode, error) { |
| 39 | labelCommandLog.Printf("Building label-command condition: labels=%v, events=%v, has_other_events=%t", |
| 40 | labelNames, labelCommandEvents, hasOtherEvents) |
| 41 | |
| 42 | if len(labelNames) == 0 { |
| 43 | return nil, errors.New("no label names provided for label-command trigger") |
| 44 | } |
| 45 | |
| 46 | filteredEvents := FilterLabelCommandEvents(labelCommandEvents) |
| 47 | if len(filteredEvents) == 0 { |
| 48 | return nil, errors.New("no valid events specified for label-command trigger") |
| 49 | } |
| 50 | |
| 51 | // Build the label-name match condition: label1 == name OR label2 == name ... |
| 52 | var labelNameChecks []ConditionNode |
| 53 | for _, labelName := range labelNames { |
| 54 | labelNameChecks = append(labelNameChecks, BuildEquals( |
| 55 | BuildPropertyAccess("github.event.label.name"), |
| 56 | BuildStringLiteral(labelName), |
| 57 | )) |
| 58 | } |
| 59 | var labelNameMatch ConditionNode |
| 60 | if len(labelNameChecks) == 1 { |
| 61 | labelNameMatch = labelNameChecks[0] |
| 62 | } else { |
| 63 | labelNameMatch = BuildDisjunction(false, labelNameChecks...) |
| 64 | } |
| 65 | |
| 66 | // Build per-event checks: (event_name == 'issues' AND label matches) OR ... |
| 67 | var eventChecks []ConditionNode |
| 68 | for _, event := range filteredEvents { |
| 69 | eventChecks = append(eventChecks, &AndNode{ |
| 70 | Left: BuildEventTypeEquals(event), |
| 71 | Right: labelNameMatch, |
| 72 | }) |
| 73 | } |
| 74 | labelCondition := BuildDisjunction(false, eventChecks...) |
| 75 | |
| 76 | if !hasOtherEvents { |
| 77 | // No other events — the label condition is the entire condition. |
| 78 | return labelCondition, nil |
| 79 | } |
| 80 | |
| 81 | // When there are other events (e.g. workflow_dispatch from the expanded shorthand, or |
| 82 | // user-supplied events), we allow non-label events through unconditionally and only |
| 83 | // require the label-name check for label events. |
| 84 | var labelEventChecks []ConditionNode |
| 85 | for _, event := range filteredEvents { |
| 86 | labelEventChecks = append(labelEventChecks, BuildEventTypeEquals(event)) |
| 87 | } |
| 88 | isLabelEvent := BuildDisjunction(false, labelEventChecks...) |
| 89 | isNotLabelEvent := &NotNode{Child: isLabelEvent} |
| 90 | |
| 91 | return &OrNode{ |
| 92 | Left: &AndNode{Left: isLabelEvent, Right: labelNameMatch}, |
| 93 | Right: isNotLabelEvent, |
| 94 | }, nil |
| 95 | } |