func()

in bigquery/main.go [203:317]


func (n *bqNotifier) SendNotification(ctx context.Context, build *cbpb.Build) error {
	if !n.filter.Apply(ctx, build) {
		log.V(2).Infof("not doing BQ write for build %v", build.Id)
		return nil
	}
	if build.BuildTriggerId == "" {
		log.Warningf("build passes filter but does not have a trigger ID. Build id: %q, status: %v", build.Id, build.GetStatus())
	}
	if !terminalStatusCodes[build.Status] {
		log.Infof("not writing to BigQuery for non-terminal build status %v", build.Status.String())
		return nil
	}
	log.Infof("sending Big Query write for build %q (status: %q)", build.Id, build.Status)
	if build.ProjectId == "" {
		return fmt.Errorf("build missing project id")
	}
	buildImages := []*buildImage{}
	shaSet := make(map[string]bool)
	if build.Status == cbpb.Build_SUCCESS {
		for _, image := range build.GetImages() {
			buildImage, err := imageManifestToBuildImage(image)
			if err != nil {
				return fmt.Errorf("error parsing image manifest: %v", err)
			}
			if shaSet[buildImage.SHA] {
				continue
			}
			shaSet[buildImage.SHA] = true
			buildImages = append(buildImages, buildImage)
		}
	}
	buildSteps := []*buildStep{}
	createTime, err := parsePBTime(build.CreateTime)
	if err != nil {
		return fmt.Errorf("error parsing CreateTime: %v", err)
	}
	startTime, err := parsePBTime(build.StartTime)
	if err != nil {
		return fmt.Errorf("error parsing StartTime: %v", err)
	}
	finishTime, err := parsePBTime(build.FinishTime)
	if err != nil {
		return fmt.Errorf("error parsing FinishTime: %v", err)
	}
	unixZeroTimestamp := timestamppb.New(time.Unix(0, 0))
	for _, step := range build.GetSteps() {
		st := step.GetTiming().GetStartTime()
		et := step.GetTiming().GetEndTime()
		if st == nil {
			st = unixZeroTimestamp
		}
		if et == nil {
			et = unixZeroTimestamp
		}
		startTime, err := parsePBTime(st)
		if err != nil {
			return fmt.Errorf("error parsing StartTime: %v", err)
		}
		endTime, err := parsePBTime(et)
		if err != nil {
			return fmt.Errorf("error parsing EndTime: %v", err)
		}
		newStep := &buildStep{
			Name:      step.Name,
			ID:        step.Id,
			Status:    step.GetStatus().String(),
			Args:      step.Args,
			StartTime: startTime,
			EndTime:   endTime,
		}
		buildSteps = append(buildSteps, newStep)
	}
	logURL, err := notifiers.AddUTMParams(build.LogUrl, notifiers.StorageMedium)
	if err != nil {
		return fmt.Errorf("error generating UTM params: %v", err)
	}
	substitutions := []*substitution{}
	for key, value := range build.Substitutions {
		substitutions = append(substitutions, &substitution{key, value})
	}
	var bindings map[string]string
	if n.br != nil {
		bindings, err = n.br.Resolve(ctx, nil, build)
		if err != nil {
			return fmt.Errorf("failed to resolve bindings: %w", err)
		}
	}

	n.tmplView = &notifiers.TemplateView{
		Build:  &notifiers.BuildView{Build: build},
		Params: bindings,
	}
	var buf bytes.Buffer
	if err := n.tmpl.Execute(&buf, n.tmplView); err != nil {
		return err
	}

	newRow := &bqRow{
		ProjectID:      build.ProjectId,
		ID:             build.Id,
		BuildTriggerID: build.BuildTriggerId,
		Status:         build.Status.String(),
		Images:         buildImages,
		Steps:          buildSteps,
		CreateTime:     createTime,
		StartTime:      startTime,
		FinishTime:     finishTime,
		Tags:           build.Tags,
		Env:            build.Options.Env,
		LogURL:         logURL,
		Substitutions:  substitutions,
		JSON:           buf.String(),
	}
	return n.client.WriteRow(ctx, newRow)
}