Repository: jenkins-x/lighthouse
Pull request #1051 (2020-09-12 09:18:17)

refactor: sigmention plugin
This PR refactors the sigmention plugin.

The sigmention plugin does not follow the command concept, it catches all generic comment events and doesn't require matching a regex with a command like format.

To address this behavior i decoupled the `CommandEventHandler` and `GenericCommentEventHandler`. The former receives a regex match while the latter just receives the event and doesn't have an associated command help. 

jenkins-x-bot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by:
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **eddycharly**
You can assign the PR to them by writing `/assign @eddycharly` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=jenkins-x%2Flighthouse).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/jenkins-x/lighthouse/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["eddycharly"]} -->
jenkins-x-bot: @eddycharly: The following test **failed**, say `/retest` to rerun them all:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ghe | 08625bdd6f697937205680dc712c1049ff5b4f03 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/2) | `/test ghe`

[View all Builds for this Pull Request](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051) 

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [jenkins-x/lighthouse](https://github.com/jenkins-x/lighthouse/issues/new?title=Command%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
jenkins-x-bot: @eddycharly: The following tests **failed**, say `/retest` to rerun them all:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ghe | 08625bdd6f697937205680dc712c1049ff5b4f03 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/2) | `/test ghe`
gitlab | 08625bdd6f697937205680dc712c1049ff5b4f03 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/5) | `/test gitlab`

[View all Builds for this Pull Request](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051) 

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [jenkins-x/lighthouse](https://github.com/jenkins-x/lighthouse/issues/new?title=Command%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
jenkins-x-bot: @eddycharly: The following tests **failed**, say `/retest` to rerun them all:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ghe | 08625bdd6f697937205680dc712c1049ff5b4f03 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/2) | `/test ghe`
gitlab | 08625bdd6f697937205680dc712c1049ff5b4f03 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/5) | `/test gitlab`
github | 08625bdd6f697937205680dc712c1049ff5b4f03 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/3) | `/test github`

[View all Builds for this Pull Request](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051) 

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [jenkins-x/lighthouse](https://github.com/jenkins-x/lighthouse/issues/new?title=Command%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
jenkins-x-bot: @eddycharly: The following tests **failed**, say `/retest` to rerun them all:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ghe | 08625bdd6f697937205680dc712c1049ff5b4f03 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/2) | `/test ghe`
gitlab | 08625bdd6f697937205680dc712c1049ff5b4f03 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/5) | `/test gitlab`
github | 08625bdd6f697937205680dc712c1049ff5b4f03 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/3) | `/test github`
tekton | 08625bdd6f697937205680dc712c1049ff5b4f03 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/6) | `/test tekton`

[View all Builds for this Pull Request](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051) 

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [jenkins-x/lighthouse](https://github.com/jenkins-x/lighthouse/issues/new?title=Command%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
jenkins-x-bot: @eddycharly: The following tests **failed**, say `/retest` to rerun them all:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ghe | 08625bdd6f697937205680dc712c1049ff5b4f03 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/2) | `/test ghe`
gitlab | 08625bdd6f697937205680dc712c1049ff5b4f03 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/5) | `/test gitlab`
github | 08625bdd6f697937205680dc712c1049ff5b4f03 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/3) | `/test github`
tekton | 08625bdd6f697937205680dc712c1049ff5b4f03 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/6) | `/test tekton`
bbs | 08625bdd6f697937205680dc712c1049ff5b4f03 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/4) | `/test bbs`

[View all Builds for this Pull Request](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051) 

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [jenkins-x/lighthouse](https://github.com/jenkins-x/lighthouse/issues/new?title=Command%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
abayer: /lgtm
jenkins-x-bot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *[abayer](https://github.com/jenkins-x/lighthouse/pull/1051#issuecomment-691503363 "LGTM")*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=jenkins-x%2Flighthouse).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com#issuecomment-691503363/jenkins-x/lighthouse/blob/master/OWNERS)~~ [abayer]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
jenkins-x-bot: @eddycharly: The following tests **failed**, say `/retest` to rerun them all:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
tekton | 08625bdd6f697937205680dc712c1049ff5b4f03 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/6) | `/test tekton`
pr-build | 9c07213c5ccc21788e6b2e35a713776e737a9d97 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/13) | `/test pr-build`

[View all Builds for this Pull Request](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051) 

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [jenkins-x/lighthouse](https://github.com/jenkins-x/lighthouse/issues/new?title=Command%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
abayer: /retest
jenkins-x-bot: @eddycharly: The following test **failed**, say `/retest` to rerun them all:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pr-build | 9c07213c5ccc21788e6b2e35a713776e737a9d97 | [link](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051/19) | `/test pr-build`

[View all Builds for this Pull Request](https://dashboard-jx.jenkins-x.live/teams/jx/projects/jenkins-x/lighthouse/PR-1051) 

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [jenkins-x/lighthouse](https://github.com/jenkins-x/lighthouse/issues/new?title=Command%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
abayer: Legit vet failure in override:
```
vet: pkg/plugins/override/override_test.go:432:47: cannot use (func(handler plugins.GenericCommentHandler, e *scmprovider.GenericCommentEvent, match []string) error literal) (value of type func(handler plugins.GenericCommentHandler, e *scmprovider.GenericCommentEvent, match []string) error) as func(plugins.CommandEventHandler, *scmprovider.GenericCommentEvent, []string) error value in argument to plugin.InvokeCommandHandler
```
jenkins-x-bot: New changes are detected. LGTM label has been removed.
jenkins-x-bot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *[abayer](https://github.com/jenkins-x/lighthouse/pull/1051#issuecomment-691503363 "LGTM")*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=jenkins-x%2Flighthouse).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/jenkins-x/lighthouse/blob/master/OWNERS)~~ [abayer]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
eddycharly: Thanks, it should be fixed now.
abayer: /lgtm
jenkins-x-bot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *[abayer](https://github.com/jenkins-x/lighthouse/pull/1051#issuecomment-691524901 "LGTM")*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=jenkins-x%2Flighthouse).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com#issuecomment-691524901/jenkins-x/lighthouse/blob/master/OWNERS)~~ [abayer]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->

Patch:
diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go
index 9b47a39e..6572b075 100644
--- a/pkg/plugins/plugins.go
+++ b/pkg/plugins/plugins.go
@@ -50,7 +50,7 @@ type Command struct {
 	Regex                 *regexp.Regexp
 	MaxMatches            int
 	Filter                func(e scmprovider.GenericCommentEvent) bool
-	GenericCommentHandler GenericCommentHandler
+	GenericCommentHandler CommandEventHandler
 }
 
 // InvokeHandler performs command checks (filter, then regex if any) the calls the handler with the match (if any)
@@ -75,7 +75,7 @@ func (cmd Command) InvokeHandler(ce *scmprovider.GenericCommentEvent, handler fu
 }
 
 // InvokeCommandHandler performs command checks (filter, then regex if any) the calls the handler with the match (if any)
-func (cmd Command) InvokeCommandHandler(ce *scmprovider.GenericCommentEvent, handler func(GenericCommentHandler, *scmprovider.GenericCommentEvent, []string) error) error {
+func (cmd Command) InvokeCommandHandler(ce *scmprovider.GenericCommentEvent, handler func(CommandEventHandler, *scmprovider.GenericCommentEvent, []string) error) error {
 	if cmd.GenericCommentHandler == nil || (cmd.Filter != nil && !cmd.Filter(*ce)) {
 		return nil
 	}
@@ -112,14 +112,15 @@ func (cmd Command) GetMatches(ce *scmprovider.GenericCommentEvent) ([][]string,
 
 // Plugin defines a plugin and its handlers
 type Plugin struct {
-	Description        string
-	ConfigHelpProvider ConfigHelpProvider
-	IssueHandler       IssueHandler
-	PullRequestHandler PullRequestHandler
-	PushEventHandler   PushEventHandler
-	ReviewEventHandler ReviewEventHandler
-	StatusEventHandler StatusEventHandler
-	Commands           []Command
+	Description           string
+	ConfigHelpProvider    ConfigHelpProvider
+	IssueHandler          IssueHandler
+	PullRequestHandler    PullRequestHandler
+	PushEventHandler      PushEventHandler
+	ReviewEventHandler    ReviewEventHandler
+	StatusEventHandler    StatusEventHandler
+	GenericCommentHandler GenericCommentHandler
+	Commands              []Command
 }
 
 // InvokeCommand calls InvokeHandler on all commands
@@ -133,7 +134,7 @@ func (plugin Plugin) InvokeCommand(ce *scmprovider.GenericCommentEvent, handler
 }
 
 // InvokeCommandHandler calls InvokeHandler on all commands
-func (plugin Plugin) InvokeCommandHandler(ce *scmprovider.GenericCommentEvent, handler func(GenericCommentHandler, *scmprovider.GenericCommentEvent, []string) error) error {
+func (plugin Plugin) InvokeCommandHandler(ce *scmprovider.GenericCommentEvent, handler func(CommandEventHandler, *scmprovider.GenericCommentEvent, []string) error) error {
 	for _, cmd := range plugin.Commands {
 		if err := cmd.InvokeCommandHandler(ce, handler); err != nil {
 			return err
@@ -157,9 +158,6 @@ type ConfigHelpProvider func(config *Configuration, enabledRepos []string) (map[
 // IssueHandler defines the function contract for a scm.Issue handler.
 type IssueHandler func(Agent, scm.Issue) error
 
-// IssueCommentHandler defines the function contract for a scm.Comment handler.
-type IssueCommentHandler func(Agent, scm.IssueCommentHook) error
-
 // PullRequestHandler defines the function contract for a scm.PullRequest handler.
 type PullRequestHandler func(Agent, scm.PullRequestHook) error
 
@@ -172,11 +170,11 @@ type PushEventHandler func(Agent, scm.PushHook) error
 // ReviewEventHandler defines the function contract for a ReviewHook handler.
 type ReviewEventHandler func(Agent, scm.ReviewHook) error
 
-// ReviewCommentEventHandler defines the function contract for a scm.PullRequestCommentHook handler.
-type ReviewCommentEventHandler func(Agent, scm.PullRequestCommentHook) error
-
 // GenericCommentHandler defines the function contract for a scm.Comment handler.
-type GenericCommentHandler func([]string, Agent, scmprovider.GenericCommentEvent) error
+type GenericCommentHandler func(Agent, scmprovider.GenericCommentEvent) error
+
+// CommandEventHandler defines the function contract for a command handler.
+type CommandEventHandler func([]string, Agent, scmprovider.GenericCommentEvent) error
 
 // HelpProviders returns the map of registered plugins with their associated HelpProvider.
 func HelpProviders() map[string]HelpProvider {
diff --git a/pkg/plugins/sigmention/sigmention.go b/pkg/plugins/sigmention/sigmention.go
index 066d2b19..0e103c04 100644
--- a/pkg/plugins/sigmention/sigmention.go
+++ b/pkg/plugins/sigmention/sigmention.go
@@ -55,14 +55,6 @@ type scmProviderClient interface {
 	QuoteAuthorForComment(string) string
 }
 
-var (
-	sigmentionCommand = plugins.Command{
-		// TODO help
-		Filter:                func(e scmprovider.GenericCommentEvent) bool { return e.Action == scm.ActionCreate },
-		GenericCommentHandler: handleGenericComment,
-	}
-)
-
 func init() {
 	description := `The sigmention plugin responds to SIG (Special Interest Group) GitHub team mentions like '@kubernetes/sig-testing-bugs'. The plugin responds in two ways:
 <ol><li> The appropriate 'sig/*' and 'kind/*' labels are applied to the issue or pull request. In this case 'sig/testing' and 'kind/bug'.</li>
@@ -71,11 +63,9 @@ func init() {
 	plugins.RegisterPlugin(
 		pluginName,
 		plugins.Plugin{
-			Description:        description,
-			ConfigHelpProvider: configHelp,
-			Commands: []plugins.Command{
-				sigmentionCommand,
-			},
+			Description:           description,
+			ConfigHelpProvider:    configHelp,
+			GenericCommentHandler: handleGenericComment,
 		},
 	)
 }
@@ -87,7 +77,7 @@ func configHelp(config *plugins.Configuration, enabledRepos []string) (map[strin
 		nil
 }
 
-func handleGenericComment(_ []string, pc plugins.Agent, e scmprovider.GenericCommentEvent) error {
+func handleGenericComment(pc plugins.Agent, e scmprovider.GenericCommentEvent) error {
 	return handle(pc.SCMProviderClient, pc.Logger, &e, pc.PluginConfig.SigMention.Re)
 }
 
@@ -117,15 +107,15 @@ func handle(spc scmProviderClient, log *logrus.Entry, e *scmprovider.GenericComm
 	if err != nil {
 		return err
 	}
-	RepoLabelsExisting := map[string]string{}
+	repoLabelsExisting := map[string]string{}
 	for _, l := range repoLabels {
-		RepoLabelsExisting[strings.ToLower(l.Name)] = l.Name
+		repoLabelsExisting[strings.ToLower(l.Name)] = l.Name
 	}
 
 	var nonexistent, toRepeat []string
 	for _, sigMatch := range sigMatches {
 		sigLabel := strings.ToLower("sig" + "/" + sigMatch[1])
-		sigLabel, ok := RepoLabelsExisting[sigLabel]
+		sigLabel, ok := repoLabelsExisting[sigLabel]
 		if !ok {
 			nonexistent = append(nonexistent, "sig/"+sigMatch[1])
 			continue
diff --git a/pkg/webhook/events.go b/pkg/webhook/events.go
index 9f5c9f94..21906627 100644
--- a/pkg/webhook/events.go
+++ b/pkg/webhook/events.go
@@ -107,10 +107,20 @@ func (s *Server) handlePullRequestCommentEvent(l *logrus.Entry, pc scm.PullReque
 
 func (s *Server) handleGenericComment(l *logrus.Entry, ce *scmprovider.GenericCommentEvent) {
 	for p, h := range s.Plugins.GetPlugins(ce.Repo.Namespace, ce.Repo.Name) {
+		if h.GenericCommentHandler != nil {
+			s.wg.Add(1)
+			go func(p string, h plugins.GenericCommentHandler) {
+				defer s.wg.Done()
+				agent := plugins.NewAgent(s.ConfigAgent, s.Plugins, s.ClientAgent, s.ServerURL, l.WithField("plugin", p))
+				if err := h(agent, *ce); err != nil {
+					agent.Logger.WithError(err).Error("Error handling GenericCommentEvent.")
+				}
+			}(p, h.GenericCommentHandler)
+		}
 		for _, cmd := range h.Commands {
 			err := cmd.InvokeHandler(ce, func(match []string) error {
 				s.wg.Add(1)
-				go func(p string, h plugins.GenericCommentHandler, m []string) {
+				go func(p string, h plugins.CommandEventHandler, m []string) {
 					defer s.wg.Done()
 					agent := plugins.NewAgent(s.ConfigAgent, s.Plugins, s.ClientAgent, s.ServerURL, l.WithField("plugin", p))
 					agent.InitializeCommentPruner(


Test patch:
diff --git a/pkg/plugins/dog/dog_test.go b/pkg/plugins/dog/dog_test.go
index 46f26575..ac59a760 100644
--- a/pkg/plugins/dog/dog_test.go
+++ b/pkg/plugins/dog/dog_test.go
@@ -230,7 +230,7 @@ func TestHttpResponse(t *testing.T) {
 			Logger:            logrus.WithField("plugin", pluginName),
 		}
 		plugin := createPlugin(realPack(ts.URL))
-		err = plugin.InvokeCommandHandler(e, func(handler plugins.GenericCommentHandler, e *scmprovider.GenericCommentEvent, match []string) error {
+		err = plugin.InvokeCommandHandler(e, func(handler plugins.CommandEventHandler, e *scmprovider.GenericCommentEvent, match []string) error {
 			return handler(match, agent, *e)
 		})
 		if err != nil {
@@ -357,7 +357,7 @@ func TestDogs(t *testing.T) {
 				Logger:            logrus.WithField("plugin", pluginName),
 			}
 			plugin := createPlugin(fakePack("http://127.0.0.1"))
-			err := plugin.InvokeCommandHandler(e, func(handler plugins.GenericCommentHandler, e *scmprovider.GenericCommentEvent, match []string) error {
+			err := plugin.InvokeCommandHandler(e, func(handler plugins.CommandEventHandler, e *scmprovider.GenericCommentEvent, match []string) error {
 				return handler(match, agent, *e)
 			})
 			if err != nil {
diff --git a/pkg/plugins/label/label_test.go b/pkg/plugins/label/label_test.go
index cb2d9135..f6b00a2a 100644
--- a/pkg/plugins/label/label_test.go
+++ b/pkg/plugins/label/label_test.go
@@ -496,7 +496,7 @@ func TestLabel(t *testing.T) {
 					},
 				},
 			}
-			err := plugin.InvokeCommandHandler(e, func(handler plugins.GenericCommentHandler, e *scmprovider.GenericCommentEvent, match []string) error {
+			err := plugin.InvokeCommandHandler(e, func(handler plugins.CommandEventHandler, e *scmprovider.GenericCommentEvent, match []string) error {
 				return handler(match, agent, *e)
 			})
 			if err != nil {
diff --git a/pkg/plugins/milestonestatus/milestonestatus_test.go b/pkg/plugins/milestonestatus/milestonestatus_test.go
index 8234e818..6718c3bb 100644
--- a/pkg/plugins/milestonestatus/milestonestatus_test.go
+++ b/pkg/plugins/milestonestatus/milestonestatus_test.go
@@ -152,7 +152,7 @@ func TestMilestoneStatus(t *testing.T) {
 					RepoMilestone: repoMilestone,
 				},
 			}
-			if err := plugin.InvokeCommandHandler(e, func(handler plugins.GenericCommentHandler, e *scmprovider.GenericCommentEvent, match []string) error {
+			if err := plugin.InvokeCommandHandler(e, func(handler plugins.CommandEventHandler, e *scmprovider.GenericCommentEvent, match []string) error {
 				return handler(match, agent, *e)
 			}); err != nil {
 				t.Fatalf("(%s): Unexpected error from handle: %v.", tc.name, err)
diff --git a/pkg/plugins/override/override_test.go b/pkg/plugins/override/override_test.go
index d42da7b9..2661a54d 100644
--- a/pkg/plugins/override/override_test.go
+++ b/pkg/plugins/override/override_test.go
@@ -429,7 +429,7 @@ func TestHandle(t *testing.T) {
 					},
 				},
 			}
-			err := plugin.InvokeCommandHandler(&event, func(handler plugins.GenericCommentHandler, e *scmprovider.GenericCommentEvent, match []string) error {
+			err := plugin.InvokeCommandHandler(&event, func(handler plugins.CommandEventHandler, e *scmprovider.GenericCommentEvent, match []string) error {
 				return handler(match, agent, event)
 			})
 			switch {
diff --git a/pkg/plugins/pony/pony_test.go b/pkg/plugins/pony/pony_test.go
index bf1c4459..a5fecc62 100644
--- a/pkg/plugins/pony/pony_test.go
+++ b/pkg/plugins/pony/pony_test.go
@@ -230,7 +230,7 @@ func TestHttpResponse(t *testing.T) {
 				Logger:            logrus.WithField("plugin", pluginName),
 			}
 			plugin := createPlugin(realHerd(ts.URL + testcase.path))
-			err = plugin.InvokeCommandHandler(e, func(handler plugins.GenericCommentHandler, e *scmprovider.GenericCommentEvent, match []string) error {
+			err = plugin.InvokeCommandHandler(e, func(handler plugins.CommandEventHandler, e *scmprovider.GenericCommentEvent, match []string) error {
 				return handler(match, agent, *e)
 			})
 			if err != nil {
@@ -331,7 +331,7 @@ func TestPonies(t *testing.T) {
 			Logger:            logrus.WithField("plugin", pluginName),
 		}
 		plugin := createPlugin(fakeHerd("pone"))
-		err := plugin.InvokeCommandHandler(e, func(handler plugins.GenericCommentHandler, e *scmprovider.GenericCommentEvent, match []string) error {
+		err := plugin.InvokeCommandHandler(e, func(handler plugins.CommandEventHandler, e *scmprovider.GenericCommentEvent, match []string) error {
 			return handler(match, agent, *e)
 		})
 		if err != nil {
diff --git a/pkg/plugins/shrug/shurg_test.go b/pkg/plugins/shrug/shurg_test.go
index afeaa7fb..6dac50f9 100644
--- a/pkg/plugins/shrug/shurg_test.go
+++ b/pkg/plugins/shrug/shurg_test.go
@@ -89,7 +89,7 @@ func TestShrugComment(t *testing.T) {
 		if tc.hasShrug {
 			fc.IssueLabelsAdded = []string{"org/repo#5:" + labels.Shrug}
 		}
-		if err := plugin.InvokeCommandHandler(e, func(handler plugins.GenericCommentHandler, e *scmprovider.GenericCommentEvent, match []string) error {
+		if err := plugin.InvokeCommandHandler(e, func(handler plugins.CommandEventHandler, e *scmprovider.GenericCommentEvent, match []string) error {
 			return handler(match, agent, *e)
 		}); err != nil {
 			t.Errorf("For case %s, didn't expect error: %v", tc.name, err)
diff --git a/pkg/plugins/stage/stage_test.go b/pkg/plugins/stage/stage_test.go
index e72cc691..71097744 100644
--- a/pkg/plugins/stage/stage_test.go
+++ b/pkg/plugins/stage/stage_test.go
@@ -203,7 +203,7 @@ func TestStageLabels(t *testing.T) {
 				SCMProviderClient: &fakeClient.Client,
 				Logger:            logrus.WithField("plugin", pluginName),
 			}
-			err := plugin.InvokeCommandHandler(e, func(handler plugins.GenericCommentHandler, e *scmprovider.GenericCommentEvent, match []string) error {
+			err := plugin.InvokeCommandHandler(e, func(handler plugins.CommandEventHandler, e *scmprovider.GenericCommentEvent, match []string) error {
 				return handler(match, agent, *e)
 			})
 			switch {
diff --git a/pkg/plugins/yuks/yuks_test.go b/pkg/plugins/yuks/yuks_test.go
index 7717fa5f..1d85afa2 100644
--- a/pkg/plugins/yuks/yuks_test.go
+++ b/pkg/plugins/yuks/yuks_test.go
@@ -73,7 +73,7 @@ func TestJokesMedium(t *testing.T) {
 		Logger:            logrus.WithField("plugin", pluginName),
 	}
 	plugin := createPlugin(realJoke(ts.URL))
-	if err := plugin.InvokeCommandHandler(e, func(handler plugins.GenericCommentHandler, e *scmprovider.GenericCommentEvent, match []string) error {
+	if err := plugin.InvokeCommandHandler(e, func(handler plugins.CommandEventHandler, e *scmprovider.GenericCommentEvent, match []string) error {
 		return handler(match, agent, *e)
 	}); err != nil {
 		t.Errorf("didn't expect error: %v", err)
@@ -174,7 +174,7 @@ func TestJokes(t *testing.T) {
 				Logger:            logrus.WithField("plugin", pluginName),
 			}
 			plugin := createPlugin(tc.joke)
-			err := plugin.InvokeCommandHandler(e, func(handler plugins.GenericCommentHandler, e *scmprovider.GenericCommentEvent, match []string) error {
+			err := plugin.InvokeCommandHandler(e, func(handler plugins.CommandEventHandler, e *scmprovider.GenericCommentEvent, match []string) error {
 				return handler(match, agent, *e)
 			})
 			if !tc.shouldError && err != nil {