in prow/plugins/trigger/generic-comment.go [33:171]
func handleGenericComment(c Client, trigger plugins.Trigger, gc github.GenericCommentEvent) error {
org := gc.Repo.Owner.Login
repo := gc.Repo.Name
number := gc.Number
commentAuthor := gc.User.Login
// Only take action when a comment is first created,
// when it belongs to a PR,
// and the PR is open.
if gc.Action != github.GenericCommentActionCreated || !gc.IsPR || gc.IssueState != "open" {
return nil
}
// Skip bot comments.
botUserChecker, err := c.GitHubClient.BotUserChecker()
if err != nil {
return err
}
if botUserChecker(commentAuthor) {
c.Logger.Debug("Comment is made by the bot, skipping.")
return nil
}
refGetter := config.NewRefGetterForGitHubPullRequest(c.GitHubClient, org, repo, number)
presubmits := getPresubmits(c.Logger, c.GitClient, c.Config, org+"/"+repo, refGetter.BaseSHA, refGetter.HeadSHA)
// Skip comments not germane to this plugin
if !pjutil.RetestRe.MatchString(gc.Body) &&
!pjutil.RetestRequiredRe.MatchString(gc.Body) &&
!pjutil.OkToTestRe.MatchString(gc.Body) &&
!pjutil.TestAllRe.MatchString(gc.Body) &&
!pjutil.MayNeedHelpComment(gc.Body) {
matched := false
for _, presubmit := range presubmits {
matched = matched || presubmit.TriggerMatches(gc.Body)
if matched {
break
}
}
if !matched {
c.Logger.Debug("Comment doesn't match any triggering regex, skipping.")
return nil
}
}
// Skip untrusted users comments.
trustedResponse, err := TrustedUser(c.GitHubClient, trigger.OnlyOrgMembers, trigger.TrustedApps, trigger.TrustedOrg, commentAuthor, org, repo)
if err != nil {
return fmt.Errorf("error checking trust of %s: %w", commentAuthor, err)
}
trusted := trustedResponse.IsTrusted
var l []github.Label
if !trusted {
// Skip untrusted PRs.
l, trusted, err = TrustedPullRequest(c.GitHubClient, trigger, gc.IssueAuthor.Login, org, repo, number, nil)
if err != nil {
return err
}
if !trusted {
resp := "Cannot trigger testing until a trusted user reviews the PR and leaves an `/ok-to-test` message."
c.Logger.Infof("Commenting \"%s\".", resp)
return c.GitHubClient.CreateComment(org, repo, number, plugins.FormatResponseRaw(gc.Body, gc.HTMLURL, gc.User.Login, resp))
}
}
// At this point we can trust the PR, so we eventually update labels.
// Ensure we have labels before test, because TrustedPullRequest() won't be called
// when commentAuthor is trusted.
if l == nil {
l, err = c.GitHubClient.GetIssueLabels(org, repo, number)
if err != nil {
return err
}
}
isOkToTest := HonorOkToTest(trigger) && pjutil.OkToTestRe.MatchString(gc.Body)
if isOkToTest && !github.HasLabel(labels.OkToTest, l) {
if err := c.GitHubClient.AddLabel(org, repo, number, labels.OkToTest); err != nil {
return err
}
}
if (isOkToTest || github.HasLabel(labels.OkToTest, l)) && github.HasLabel(labels.NeedsOkToTest, l) {
if err := c.GitHubClient.RemoveLabel(org, repo, number, labels.NeedsOkToTest); err != nil {
return err
}
}
pr, err := refGetter.PullRequest()
if err != nil {
return err
}
baseSHA, err := refGetter.BaseSHA()
if err != nil {
return err
}
toTest, err := FilterPresubmits(HonorOkToTest(trigger), c.GitHubClient, gc.Body, pr, presubmits, c.Logger)
if err != nil {
return err
}
if needsHelp, note := pjutil.ShouldRespondWithHelp(gc.Body, len(toTest)); needsHelp {
return addHelpComment(c.GitHubClient, gc.Body, org, repo, pr.Base.Ref, pr.Number, presubmits, gc.HTMLURL, commentAuthor, note, c.Logger)
}
// we want to be able to track re-tests separately from the general body of tests
additionalLabels := map[string]string{}
if pjutil.RetestRe.MatchString(gc.Body) || pjutil.RetestRequiredRe.MatchString(gc.Body) {
additionalLabels[kube.RetestLabel] = "true"
}
// run failed github actions
if trigger.TriggerGitHubWorkflows && (pjutil.RetestRe.MatchString(gc.Body) || pjutil.TestAllRe.MatchString(gc.Body)) {
headSHA, err := refGetter.HeadSHA()
if err != nil {
c.Logger.Warnf("headSHA unvailable, failed github actions for pr will not be triggered: %v", pr)
} else {
failedRuns, err := c.GitHubClient.GetFailedActionRunsByHeadBranch(org, repo, pr.Head.Ref, headSHA)
if err != nil {
c.Logger.Errorf("%v: unable to get failed github action runs for branch %v", err, pr.Head.Ref)
} else {
for _, run := range failedRuns {
log := c.Logger.WithFields(logrus.Fields{
"runID": run.ID,
"runName": run.Name,
"org": org,
"repo": repo,
})
runID := run.ID
go func() {
if err := c.GitHubClient.TriggerGitHubWorkflow(org, repo, runID); err != nil {
log.Errorf("attempt to trigger github run failed: %v", err)
} else {
log.Infof("successfully triggered action run")
}
}()
}
}
}
}
return RunRequestedWithLabels(c, pr, baseSHA, toTest, gc.GUID, additionalLabels)
}