prow/gerrit/reporter/reporter.go
func (c *Client) Report(pj *v1.ProwJob) ([]*v1.ProwJob, error) {

	logger := logrus.WithField("prowjob", pj)

	clientGerritRevision := client.GerritRevision
	clientGerritID := client.GerritID
	clientGerritInstance := client.GerritInstance
	pjTypeLabel := kube.ProwJobTypeLabel
	gerritReportLabel := client.GerritReportLabel

	selector := labels.Set{
		clientGerritRevision: pj.ObjectMeta.Labels[clientGerritRevision],
		pjTypeLabel:          pj.ObjectMeta.Labels[pjTypeLabel],
	}
	if pj.ObjectMeta.Labels[gerritReportLabel] == "" {
		// Shouldn't happen, adapter should already have defaulted to Code-Review
		logger.Errorf("Gerrit report label not set for job %s", pj.Spec.Job)
	} else {
		selector[gerritReportLabel] = pj.ObjectMeta.Labels[gerritReportLabel]
	}

	// list all prowjobs in the patchset matching pj's type (pre- or post-submit)

	pjsOnRevisionWithSameLabel, err := c.lister.List(selector.AsSelector())
	if err != nil {
		logger.WithError(err).Errorf("Cannot list prowjob with selector %v", selector)
		return nil, err
	}

	// generate an aggregated report:
	success := 0
	message := ""
	var toReportJobs []*v1.ProwJob
	mostRecentJob := map[string]*v1.ProwJob{}
	for _, pjOnRevisionWithSameLabel := range pjsOnRevisionWithSameLabel {
		job, ok := mostRecentJob[pjOnRevisionWithSameLabel.Spec.Job]
		if !ok || job.CreationTimestamp.Time.Before(pjOnRevisionWithSameLabel.CreationTimestamp.Time) {
			mostRecentJob[pjOnRevisionWithSameLabel.Spec.Job] = pjOnRevisionWithSameLabel
		}
	}
	for _, pjOnRevisionWithSameLabel := range mostRecentJob {
		if pjOnRevisionWithSameLabel.Status.State == v1.AbortedState {
			continue
		}
		toReportJobs = append(toReportJobs, pjOnRevisionWithSameLabel)

		checkOrX := "❌"
		if pjOnRevisionWithSameLabel.Status.State == v1.SuccessState {
			checkOrX = "✔️"
			success++
		}

		message += fmt.Sprintf("\n\n%s %s %s - %s", checkOrX, pjOnRevisionWithSameLabel.Spec.Job, strings.ToUpper(string(pjOnRevisionWithSameLabel.Status.State)), pjOnRevisionWithSameLabel.Status.URL)
	}
	total := len(toReportJobs)
	if total <= 0 {
		// Shouldn't happen but return if does
		logger.Warn("Tried to report empty or aborted jobs.")
		return nil, nil
	}

	message = fmt.Sprintf("%d out of %d jobs passed!%s", success, total, message)

	// report back
	gerritID := pj.ObjectMeta.Annotations[clientGerritID]
	gerritInstance := pj.ObjectMeta.Annotations[clientGerritInstance]
	gerritRevision := pj.ObjectMeta.Labels[clientGerritRevision]
	reportLabel := client.CodeReview
	if val, ok := pj.ObjectMeta.Labels[client.GerritReportLabel]; ok {
		reportLabel = val
	}

	vote := client.LBTM
	if success == total {
		vote = client.LGTM
	}
	reviewLabels := map[string]string{reportLabel: vote}

	logger.Infof("Reporting to instance %s on id %s with message %s", gerritInstance, gerritID, message)
	if err := c.gc.SetReview(gerritInstance, gerritID, gerritRevision, message, reviewLabels); err != nil {
		logger.WithError(err).Errorf("fail to set review with %s label on change ID %s", reportLabel, gerritID)

		// possibly don't have label permissions, try without labels
		message = fmt.Sprintf("[NOTICE]: Prow Bot cannot access %s label!\n%s", reportLabel, message)
		if err := c.gc.SetReview(gerritInstance, gerritID, gerritRevision, message, nil); err != nil {
			logger.WithError(err).Errorf("fail to set plain review on change ID %s", gerritID)
			return nil, err
		}
	}
	logger.Infof("Review Complete, reported jobs: %v", toReportJobs)

	return toReportJobs, nil
}
func (c *Client) Report(pj *v1.ProwJob) ([]*v1.ProwJob, error) {

	logger := logrus.WithField("prowjob", pj)

	clientGerritRevision := client.GerritRevision
	clientGerritID := client.GerritID
	clientGerritInstance := client.GerritInstance
	pjTypeLabel := kube.ProwJobTypeLabel
	gerritReportLabel := client.GerritReportLabel

	selector := labels.Set{
		clientGerritRevision: pj.ObjectMeta.Labels[clientGerritRevision],
		pjTypeLabel:          pj.ObjectMeta.Labels[pjTypeLabel],
	}
	if pj.ObjectMeta.Labels[gerritReportLabel] == "" {
		// Shouldn't happen, adapter should already have defaulted to Code-Review
		logger.Errorf("Gerrit report label not set for job %s", pj.Spec.Job)
	} else {
		selector[gerritReportLabel] = pj.ObjectMeta.Labels[gerritReportLabel]
	}

	// list all prowjobs in the patchset matching pj's type (pre- or post-submit)

	pjsOnRevisionWithSameLabel, err := c.lister.List(selector.AsSelector())
	if err != nil {
		logger.WithError(err).Errorf("Cannot list prowjob with selector %v", selector)
		return nil, err
	}

	// generate an aggregated report:
	success := 0
	message := ""
	var toReportJobs []*v1.ProwJob
	mostRecentJob := map[string]*v1.ProwJob{}
	for _, pjOnRevisionWithSameLabel := range pjsOnRevisionWithSameLabel {
		job, ok := mostRecentJob[pjOnRevisionWithSameLabel.Spec.Job]
		if !ok || job.CreationTimestamp.Time.Before(pjOnRevisionWithSameLabel.CreationTimestamp.Time) {
			mostRecentJob[pjOnRevisionWithSameLabel.Spec.Job] = pjOnRevisionWithSameLabel
		}
	}
	for _, pjOnRevisionWithSameLabel := range mostRecentJob {
		if pjOnRevisionWithSameLabel.Status.State == v1.AbortedState {
			continue
		}
		toReportJobs = append(toReportJobs, pjOnRevisionWithSameLabel)

		checkOrX := "❌"
		if pjOnRevisionWithSameLabel.Status.State == v1.SuccessState {
			checkOrX = "✔️"
			success++
		}

		message += fmt.Sprintf("\n\n%s %s %s - %s", checkOrX, pjOnRevisionWithSameLabel.Spec.Job, strings.ToUpper(string(pjOnRevisionWithSameLabel.Status.State)), pjOnRevisionWithSameLabel.Status.URL)
	}
	total := len(toReportJobs)
	if total <= 0 {
		// Shouldn't happen but return if does
		logger.Warn("Tried to report empty or aborted jobs.")
		return nil, nil
	}

	message = fmt.Sprintf("%d out of %d jobs passed!%s", success, total, message)

	// report back
	gerritID := pj.ObjectMeta.Annotations[clientGerritID]
	gerritInstance := pj.ObjectMeta.Annotations[clientGerritInstance]
	gerritRevision := pj.ObjectMeta.Labels[clientGerritRevision]
	reportLabel := client.CodeReview
	if val, ok := pj.ObjectMeta.Labels[client.GerritReportLabel]; ok {
		reportLabel = val
	}

	vote := client.LBTM
	if success == total {
		vote = client.LGTM
	}
	reviewLabels := map[string]string{reportLabel: vote}

	logger.Infof("Reporting to instance %s on id %s with message %s", gerritInstance, gerritID, message)
	if err := c.gc.SetReview(gerritInstance, gerritID, gerritRevision, message, reviewLabels); err != nil {
		logger.WithError(err).Errorf("fail to set review with %s label on change ID %s", reportLabel, gerritID)

		// possibly don't have label permissions, try without labels
		message = fmt.Sprintf("[NOTICE]: Prow Bot cannot access %s label!\n%s", reportLabel, message)
		if err := c.gc.SetReview(gerritInstance, gerritID, gerritRevision, message, nil); err != nil {
			logger.WithError(err).Errorf("fail to set plain review on change ID %s", gerritID)
			return nil, err
		}
	}
	logger.Infof("Review Complete, reported jobs: %v", toReportJobs)

	return toReportJobs, nil
}
// Report will send the current prowjob status as a gerrit review