Skip to content

Commit

Permalink
Support author-in-team (#150)
Browse files Browse the repository at this point in the history
Signed-off-by: Galo Navarro <[email protected]>
  • Loading branch information
srvaroa authored Sep 6, 2024
1 parent b48bedc commit bfe2888
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 3 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ configurable matching rules. Available conditions:

* [Age](#age): label based on the age of a PR or Issue.
* [Author can merge](#author-can-merge): label based on whether the author can merge the PR
* [Author is member of team](#author-in-team): label based on whether the author is an active member of the given team
* [Authors](#authors): label based on the PR/Issue authors
* [Base branch](#base-branch): label based on the PR's base branch name
* [Body](#body): label based on the PR/Issue body
Expand Down Expand Up @@ -339,6 +340,17 @@ This is implemented by checking if the author is an owner of the repo.
```yaml
author-can-merge: True
```


### Author is member (PRs and Issues) <a name="author-in-team" />

This condition is satisfied when the author of the PR is an active
member of the given team.

```yaml
author-is-member: CoreTeam
```

### Authors (PRs and Issues) <a name="authors" />

This condition is satisfied when the author of the PR or Issue matches
Expand Down
7 changes: 7 additions & 0 deletions cmd/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,13 @@ func newLabeler(gh *github.Client, config *labeler.LabelerConfigV1) *labeler.Lab
owner, repo, &github.PullRequestListOptions{})
return prs, err
},
IsUserMemberOfTeam: func(user, team string) (bool, error) {
membership, _, err := gh.Organizations.GetOrgMembership(ctx, user, team)
if err != nil {
return false, err
}
return membership.GetState() == "active", nil
},
},
Client: labeler.NewDefaultHttpClient(),
}
Expand Down
23 changes: 23 additions & 0 deletions pkg/condition_author_in_team.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package labeler

import (
"fmt"
)

func AuthorInTeamCondition(l *Labeler) Condition {
return Condition{
GetName: func() string {
return "Author is member of team"
},
CanEvaluate: func(target *Target) bool {
return true
},
Evaluate: func(target *Target, matcher LabelMatcher) (bool, error) {
if len(matcher.AuthorInTeam) <= 0 {
return false, fmt.Errorf("author-in-team is not set in config")
}
// check if author is a member of team
return l.GitHubFacade.IsUserMemberOfTeam(target.Author, matcher.AuthorInTeam)
},
}
}
9 changes: 6 additions & 3 deletions pkg/labeler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type LabelMatcher struct {
Age string
AuthorCanMerge string `yaml:"author-can-merge"`
Authors []string
AuthorInTeam string `yaml:"author-in-team"`
BaseBranch string `yaml:"base-branch"`
Body string
Branch string
Expand Down Expand Up @@ -65,9 +66,10 @@ type LabelUpdates struct {

// Just to make this mockable..
type GitHubFacade struct {
GetRawDiff func(owner, repo string, prNumber int) (string, error)
ListIssuesByRepo func(owner, repo string) ([]*gh.Issue, error)
ListPRs func(owner, repo string) ([]*gh.PullRequest, error)
GetRawDiff func(owner, repo string, prNumber int) (string, error)
ListIssuesByRepo func(owner, repo string) ([]*gh.Issue, error)
ListPRs func(owner, repo string) ([]*gh.PullRequest, error)
IsUserMemberOfTeam func(user, team string) (bool, error)
}

type Labeler struct {
Expand Down Expand Up @@ -225,6 +227,7 @@ func (l *Labeler) findMatches(target *Target, config *LabelerConfigV1) (LabelUpd
AgeCondition(l),
AuthorCondition(),
AuthorCanMergeCondition(),
AuthorInTeamCondition(l),
BaseBranchCondition(),
BodyCondition(),
BranchCondition(),
Expand Down
44 changes: 44 additions & 0 deletions pkg/labeler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,46 @@ func TestHandleEvent(t *testing.T) {
initialLabels: []string{"Meh"},
expectedLabels: []string{"Meh", "Test"},
},
{
event: "issues",
payloads: []string{"issue_open"},
name: "Add a label to issue when author is in team",
config: LabelerConfigV1{
Version: 1,
Labels: []LabelMatcher{
{
Label: "ShouldAppear",
AuthorInTeam: "team-with-srvaroa",
},
{
Label: "ShouldNotAppear",
AuthorInTeam: "team-with",
},
},
},
initialLabels: []string{"Meh"},
expectedLabels: []string{"Meh", "ShouldAppear"},
},
{
event: "pull_request",
payloads: []string{"create_pr"},
name: "Add a label to PR when author is in team",
config: LabelerConfigV1{
Version: 1,
Labels: []LabelMatcher{
{
Label: "ShouldAppear",
AuthorInTeam: "team-with-srvaroa",
},
{
Label: "ShouldNotAppear",
AuthorInTeam: "team-with",
},
},
},
initialLabels: []string{"Meh"},
expectedLabels: []string{"Meh", "ShouldAppear"},
},
}

for _, tc := range testCases {
Expand Down Expand Up @@ -1034,6 +1074,10 @@ func NewTestLabeler(t *testing.T, tc TestCase) Labeler {
data, err := ioutil.ReadAll(file)
return string(data), nil
},
// Will return true whenever team contains the given user name
IsUserMemberOfTeam: func(user, team string) (bool, error) {
return strings.Contains(team, user), nil
},
},
}
}
Expand Down

0 comments on commit bfe2888

Please sign in to comment.