diff --git a/README.md b/README.md index 35c96e7..4e971e4 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ configurable matching rules. Available conditions: * [Mergeable](#mergeable): label based on whether the PR is mergeable * [Size](#size): label based on the PR size * [Title](#title): label based on the PR/Issue title +* [Type](#type): label based on record type (PR or Issue) ## Sponsors @@ -480,3 +481,34 @@ This condition is satisfied when the title matches on the given regex. ```yaml title: "^WIP:.*" ``` + +### Type + +By setting the type attribute in your label configuration, you can specify whether a rule applies exclusively to Pull +Requests (PRs) or Issues. This allows for more precise label management based on the type of GitHub record. The +type condition accepts one of two values: + +- `pull_request` +- `issue` + +This functionality increases the adaptability of this GitHub Action, allowing users to create more tailored labeling +strategies that differentiate between PRs and Issues or apply universally to both. + +#### Pull-Request Only: + +```yaml +- label: "needs review" + type: "pull_request" + name: ".*bug.*" +``` +This rule applies the label "needs review" to Pull Requests with "bug" in the title. + +### Issue Only: + +```yaml +- label: "needs triage" + type: "issue" + name: ".*bug.*" +``` + +This rule applies the label "needs triage" to Issues with "bug" in the title. diff --git a/cmd/action_test.go b/cmd/action_test.go index 555b35f..5ba13ce 100644 --- a/cmd/action_test.go +++ b/cmd/action_test.go @@ -264,6 +264,14 @@ func TestGetLabelerConfig2V1(t *testing.T) { Label: "TestFileMatch", Files: []string{"cmd\\/.*.go", "pkg\\/.*.go"}, }, + "TestTypePullRequest": { + Label: "TestTypePullRequest", + Type: "pull_request", + }, + "TestTypeIssue": { + Label: "TestTypeIssue", + Type: "issue", + }, } if !cmp.Equal(len(expectMatchers), len(c.Labels)) { diff --git a/pkg/condition_type.go b/pkg/condition_type.go new file mode 100644 index 0000000..f496c72 --- /dev/null +++ b/pkg/condition_type.go @@ -0,0 +1,36 @@ +package labeler + +import ( + "fmt" + "log" +) + +func TypeCondition() Condition { + return Condition{ + GetName: func() string { + return "Target type matches defined type" + }, + CanEvaluate: func(target *Target) bool { + return true + }, + Evaluate: func(target *Target, matcher LabelMatcher) (bool, error) { + if len(matcher.Type) <= 0 { + return false, fmt.Errorf("type is not set in config") + } else if matcher.Type != "pull_request" && matcher.Type != "issue" { + return false, fmt.Errorf("type musst be of value 'pull_request' or 'issue'") + } + + var targetType string + if target.ghPR != nil { + targetType = "pull_request" + } else if target.ghIssue != nil { + targetType = "issue" + } else { + return false, fmt.Errorf("target is neither pull_request nor issue") + } + + log.Printf("Matching `%s` against: `%s`", matcher.Type, targetType) + return matcher.Type == targetType || matcher.Type == "all", nil + }, + } +} diff --git a/pkg/labeler.go b/pkg/labeler.go index 286d6f4..eb19ef7 100644 --- a/pkg/labeler.go +++ b/pkg/labeler.go @@ -35,6 +35,7 @@ type LabelMatcher struct { SizeBelow string `yaml:"size-below"` // size-legacy Title string + Type string } type LabelerConfigV0 map[string]LabelMatcher @@ -226,6 +227,7 @@ func (l *Labeler) findMatches(target *Target, config *LabelerConfigV1) (LabelUpd IsMergeableCondition(), SizeCondition(l), TitleCondition(), + TypeCondition(), } for _, matcher := range config.Labels { diff --git a/pkg/labeler_test.go b/pkg/labeler_test.go index 58fc8db..5a6aea7 100644 --- a/pkg/labeler_test.go +++ b/pkg/labeler_test.go @@ -807,6 +807,70 @@ func TestHandleEvent(t *testing.T) { initialLabels: []string{"Test", "WIP"}, expectedLabels: []string{"Test", "WIP"}, }, + { + event: "issues", + payloads: []string{"issue_open"}, + name: "Add a label to issue when type matches (issues neq pull_request)", + config: LabelerConfigV1{ + Version: 1, + Labels: []LabelMatcher{ + { + Label: "Test", + Type: "pull_request", + }, + }, + }, + initialLabels: []string{"Meh"}, + expectedLabels: []string{"Meh"}, + }, + { + event: "pull_request", + payloads: []string{"create_pr"}, + name: "Add a label to pull request when type matches (pull_request neq issue)", + config: LabelerConfigV1{ + Version: 1, + Labels: []LabelMatcher{ + { + Label: "Test", + Type: "issue", + }, + }, + }, + initialLabels: []string{"Meh"}, + expectedLabels: []string{"Meh"}, + }, + { + event: "issues", + payloads: []string{"issue_open"}, + name: "Add a label to issue when type matches (issues eq issue)", + config: LabelerConfigV1{ + Version: 1, + Labels: []LabelMatcher{ + { + Label: "Test", + Type: "issue", + }, + }, + }, + initialLabels: []string{"Meh"}, + expectedLabels: []string{"Meh", "Test"}, + }, + { + event: "pull_request", + payloads: []string{"create_pr"}, + name: "Add a label to pull request when type matches (pull_request eq pull_request)", + config: LabelerConfigV1{ + Version: 1, + Labels: []LabelMatcher{ + { + Label: "Test", + Type: "pull_request", + }, + }, + }, + initialLabels: []string{"Meh"}, + expectedLabels: []string{"Meh", "Test"}, + }, } for _, tc := range testCases { diff --git a/test_data/config2_v1.yml b/test_data/config2_v1.yml index 9cbdbce..af5ab0f 100644 --- a/test_data/config2_v1.yml +++ b/test_data/config2_v1.yml @@ -7,3 +7,7 @@ labels: files: - "cmd\\/.*.go" - "pkg\\/.*.go" + - label: "TestTypePullRequest" + type: "pull_request" + - label: "TestTypeIssue" + type: "issue"