func handleGenericComment()

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)
}