Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for EasyCLA #22742

Closed
wants to merge 11 commits into from
24 changes: 18 additions & 6 deletions prow/plugins/cla/cla.go
Expand Up @@ -33,7 +33,6 @@ import (

const (
pluginName = "cla"
claContextName = "cla/linuxfoundation"
cncfclaNotFoundMessage = `Thanks for your pull request. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

:memo: **Please follow instructions at <https://git.k8s.io/community/CLA.md#the-contributor-license-agreement> to sign the CLA.**
Expand All @@ -58,7 +57,8 @@ It may take a couple minutes for the CLA signature to be fully registered; after
)

var (
checkCLARe = regexp.MustCompile(`(?mi)^/check-cla\s*$`)
checkCLARe = regexp.MustCompile(`(?mi)^/check-cla\s*$`)
claContextName string
anusha94 marked this conversation as resolved.
Show resolved Hide resolved
)

func init() {
Expand Down Expand Up @@ -93,15 +93,21 @@ type gitHubClient interface {
}

func handleStatusEvent(pc plugins.Agent, se github.StatusEvent) error {
return handle(pc.GitHubClient, pc.Logger, se)
return handle(pc.GitHubClient, pc.Logger, se, pc.PluginConfig.EasyCLAEnabled)
}

// 1. Check that the status event received from the webhook is for the CNCF-CLA.
// 2. Use the github search API to search for the PRs which match the commit hash corresponding to the status event.
// 3. For each issue that matches, check that the PR's HEAD commit hash against the commit hash for which the status
// was received. This is because we only care about the status associated with the last (latest) commit in a PR.
// 4. Set the corresponding CLA label if needed.
anusha94 marked this conversation as resolved.
Show resolved Hide resolved
func handle(gc gitHubClient, log *logrus.Entry, se github.StatusEvent) error {
func handle(gc gitHubClient, log *logrus.Entry, se github.StatusEvent, isEasyCLAEnabled bool) error {
if isEasyCLAEnabled {
claContextName = "cla/easy-cla"
anusha94 marked this conversation as resolved.
Show resolved Hide resolved
} else {
claContextName = "cla/linuxfoundation"
anusha94 marked this conversation as resolved.
Show resolved Hide resolved
}

if se.State == "" || se.Context == "" {
return fmt.Errorf("invalid status event delivered with empty state/context")
}
Expand Down Expand Up @@ -193,10 +199,16 @@ func handle(gc gitHubClient, log *logrus.Entry, se github.StatusEvent) error {
}

func handleCommentEvent(pc plugins.Agent, ce github.GenericCommentEvent) error {
return handleComment(pc.GitHubClient, pc.Logger, &ce)
return handleComment(pc.GitHubClient, pc.Logger, &ce, pc.PluginConfig.EasyCLAEnabled)
}

func handleComment(gc gitHubClient, log *logrus.Entry, e *github.GenericCommentEvent) error {
func handleComment(gc gitHubClient, log *logrus.Entry, e *github.GenericCommentEvent, isEasyCLAEnabled bool) error {
if isEasyCLAEnabled {
claContextName = "cla/easy-cla"
} else {
claContextName = "cla/linuxfoundation"
}

// Only consider open PRs and new comments.
if e.IssueState != "open" || e.Action != github.GenericCommentActionCreated {
return nil
Expand Down
85 changes: 64 additions & 21 deletions prow/plugins/cla/cla_test.go
Expand Up @@ -30,15 +30,16 @@ import (

func TestCLALabels(t *testing.T) {
var testcases = []struct {
name string
context string
state string
statusSHA string
issues []github.Issue
pullRequests []github.PullRequest
labels []string
addedLabels []string
removedLabels []string
name string
context string
state string
easyCLAEnabled bool
statusSHA string
issues []github.Issue
pullRequests []github.PullRequest
labels []string
addedLabels []string
removedLabels []string
}{
{
name: "unrecognized status context has no effect",
Expand Down Expand Up @@ -140,6 +141,21 @@ func TestCLALabels(t *testing.T) {
addedLabels: []string{fmt.Sprintf("/#3:%s", labels.ClaNo)},
removedLabels: []string{fmt.Sprintf("/#3:%s", labels.ClaYes)},
},
{
name: "cla/linuxfoundation status failure removes \"cncf-cla: yes\" label",
anusha94 marked this conversation as resolved.
Show resolved Hide resolved
context: "cla/easy-cla",
state: "failure",
easyCLAEnabled: true,
statusSHA: "a",
issues: []github.Issue{
{Number: 3, State: "open", Labels: []github.Label{{Name: labels.ClaYes}}},
},
pullRequests: []github.PullRequest{
{Number: 3, Head: github.PullRequestBranch{SHA: "a"}},
},
addedLabels: []string{fmt.Sprintf("/#3:%s", labels.ClaNo)},
removedLabels: []string{fmt.Sprintf("/#3:%s", labels.ClaYes)},
},
}
for _, tc := range testcases {
pullRequests := make(map[int]*github.PullRequest)
Expand All @@ -161,7 +177,12 @@ func TestCLALabels(t *testing.T) {
SHA: tc.statusSHA,
State: tc.state,
}
if err := handle(fc, logrus.WithField("plugin", pluginName), se); err != nil {
easyCLAEnabled := false
if tc.easyCLAEnabled {
easyCLAEnabled = true
}

if err := handle(fc, logrus.WithField("plugin", pluginName), se, easyCLAEnabled); err != nil {
t.Errorf("For case %s, didn't expect error from cla plugin: %v", tc.name, err)
continue
}
Expand All @@ -178,16 +199,17 @@ func TestCLALabels(t *testing.T) {

func TestCheckCLA(t *testing.T) {
var testcases = []struct {
name string
context string
state string
issueState string
SHA string
action string
body string
pullRequests []github.PullRequest
hasCLAYes bool
hasCLANo bool
name string
context string
easyCLAEnabled bool
state string
issueState string
SHA string
action string
body string
pullRequests []github.PullRequest
hasCLAYes bool
hasCLANo bool

addedLabel string
removedLabel string
Expand Down Expand Up @@ -330,6 +352,23 @@ func TestCheckCLA(t *testing.T) {
hasCLANo: true,
hasCLAYes: true,

removedLabel: fmt.Sprintf("/#3:%s", labels.ClaYes),
},
{
name: "cla/easy-cla status retains the cla-no label and removes cla-yes label when its state is \"failure\"",
context: "cla/easy-cla",
easyCLAEnabled: true,
state: "failure",
issueState: "open",
SHA: "sha",
action: "created",
body: "/check-cla",
pullRequests: []github.PullRequest{
{Number: 3, Head: github.PullRequestBranch{SHA: "sha"}},
},
hasCLANo: true,
hasCLAYes: true,

removedLabel: fmt.Sprintf("/#3:%s", labels.ClaYes),
},
}
Expand Down Expand Up @@ -361,7 +400,11 @@ func TestCheckCLA(t *testing.T) {
if tc.hasCLANo {
fc.IssueLabelsAdded = append(fc.IssueLabelsAdded, fmt.Sprintf("/#3:%s", labels.ClaNo))
}
if err := handleComment(fc, logrus.WithField("plugin", pluginName), e); err != nil {
easyCLAEnabled := false
if tc.easyCLAEnabled {
easyCLAEnabled = true
}
anusha94 marked this conversation as resolved.
Show resolved Hide resolved
if err := handleComment(fc, logrus.WithField("plugin", pluginName), e, easyCLAEnabled); err != nil {
t.Errorf("For case %s, didn't expect error from cla plugin: %v", tc.name, err)
}
ok := tc.addedLabel == ""
Expand Down
1 change: 1 addition & 0 deletions prow/plugins/config.go
Expand Up @@ -90,6 +90,7 @@ type Configuration struct {
Welcome []Welcome `json:"welcome,omitempty"`
Override Override `json:"override,omitempty"`
Help Help `json:"help,omitempty"`
EasyCLAEnabled bool `json:"easy_cla_enabled,omitempty"`
anusha94 marked this conversation as resolved.
Show resolved Hide resolved
}

type Help struct {
Expand Down