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
}