func CreateIssues()

in internal/worker/worker.go [177:249]


func CreateIssues(ctx context.Context, st store.Store, ic issues.Client, limit int) (err error) {
	defer derrors.Wrap(&err, "CreateIssues(destination: %s)", ic.Destination())
	ctx = event.Start(ctx, "CreateIssues")
	defer event.End(ctx)

	needsIssue, err := st.ListCVERecordsWithTriageState(ctx, store.TriageStateNeedsIssue)
	if err != nil {
		return err
	}
	log.Infof(ctx, "CreateIssues starting; destination: %s, total needing issue: %d",
		ic.Destination(), len(needsIssue))
	numCreated := int64(0)
	for _, cr := range needsIssue {
		if limit > 0 && int(numCreated) >= limit {
			break
		}
		if cr.IssueReference != "" || !cr.IssueCreatedAt.IsZero() {
			log.With(
				"CVE", cr.ID,
				"IssueReference", cr.IssueReference,
				"IssueCreatedAt", cr.IssueCreatedAt,
			).Errorf(ctx, "%s: triage state is NeedsIssue but issue field(s) non-zero; skipping", cr.ID)
			continue
		}
		body, err := newBody(cr)
		if err != nil {
			log.With(
				"CVE", cr.ID,
				"IssueReference", cr.IssueReference,
				"IssueCreatedAt", cr.IssueCreatedAt,
			).Errorf(ctx, "%s: triage state is NeedsIssue but could not generate body; skipping: %v", cr.ID, err)
			continue
		}

		// Create the issue.
		iss := &issues.Issue{
			Title: fmt.Sprintf("x/vulndb: potential Go vuln in %s: %s", cr.Module, cr.ID),
			Body:  body,
		}
		if err := issueRateLimiter.Wait(ctx); err != nil {
			return err
		}
		num, err := ic.CreateIssue(ctx, iss)
		if err != nil {
			return fmt.Errorf("creating issue for %s: %w", cr.ID, err)
		}
		// If we crashed here, we would have filed an issue without recording
		// that fact in the DB. That can lead to duplicate issues, but nothing
		// worse (we won't miss a CVE).
		// TODO(https://go.dev/issue/49733): look for the issue title to avoid duplications.
		ref := ic.Reference(num)
		log.With("CVE", cr.ID).Infof(ctx, "created issue %s for %s", ref, cr.ID)

		// Update the CVERecord in the DB with issue information.
		err = st.RunTransaction(ctx, func(ctx context.Context, tx store.Transaction) error {
			rs, err := tx.GetCVERecords(cr.ID, cr.ID)
			if err != nil {
				return err
			}
			cr := rs[0]
			cr.TriageState = store.TriageStateIssueCreated
			cr.IssueReference = ref
			cr.IssueCreatedAt = time.Now()
			return tx.SetCVERecord(cr)
		})
		if err != nil {
			return err
		}
		numCreated++
	}
	log.With("limit", limit).Infof(ctx, "CreateIssues done: %d created", numCreated)
	return nil
}