Add review workflows, tree-shaped workflows and a workflow editor

This commit is contained in:
Ian Gulliver
2026-10-20 18:52:04 -07:00
parent 9869fad988
commit f2188c53eb
31 changed files with 2179 additions and 863 deletions
+35 -12
View File
@@ -72,7 +72,7 @@ func (m *Manager) MergeAfterReview(ctx context.Context, task api.Task, user api.
}
func (m *Manager) clearMergeAfterReview(ctx context.Context, taskID string) {
_, err := m.store.TakeMergeAfterReview(ctx, taskID, "")
_, err := m.store.TakeMergeAfterReview(ctx, taskID, nil)
if err != nil {
slog.Error("clear merge after review", "task", taskID, "err", err)
}
@@ -96,7 +96,27 @@ func (m *Manager) reviewFinished(reviewID string) {
slog.Error("load finished review", "review", reviewID, "err", err)
return
}
mar, err := m.store.TakeMergeAfterReview(ctx, r.TaskId, r.Id)
if m.advanceReviews(ctx, r) {
return
}
reviews, err := m.snapshotReviews(ctx, r.TaskId, r.SnapshotN)
if err != nil {
slog.Error("list snapshot reviews", "task", r.TaskId, "err", err)
return
}
settled, err := m.reviewsSettled(ctx, reviews)
if err != nil {
slog.Error("check snapshot reviews settled", "task", r.TaskId, "err", err)
return
}
if !settled {
return
}
ids := []string{}
for _, sr := range reviews {
ids = append(ids, sr.Id)
}
mar, err := m.store.TakeMergeAfterReview(ctx, r.TaskId, ids)
if err != nil {
slog.Error("take merge after review", "task", r.TaskId, "err", err)
return
@@ -104,7 +124,7 @@ func (m *Manager) reviewFinished(reviewID string) {
if mar.By == "" {
return
}
reason := m.startMergeAfterReview(ctx, r, mar)
reason := m.startMergeAfterReview(ctx, r, reviews, mar)
if reason == "" {
slog.Info("merge after review started", "task", r.TaskId, "review", r.Id, "by", mar.By)
return
@@ -121,16 +141,19 @@ func (m *Manager) reviewFinished(reviewID string) {
}
}
func (m *Manager) startMergeAfterReview(ctx context.Context, r api.Review, mar store.MergeAfterReview) string {
switch {
case r.State == api.ReviewStateFailed:
return "the review failed"
case r.State != api.ReviewStateDone:
return fmt.Sprintf("the review ended %s", r.State)
}
func (m *Manager) startMergeAfterReview(ctx context.Context, r api.Review, reviews []api.Review, mar store.MergeAfterReview) string {
findings := []any{}
if r.Result != nil {
findings, _ = (*r.Result)["findings"].([]any)
for _, sr := range reviews {
switch {
case sr.State == api.ReviewStateFailed:
return fmt.Sprintf("the %q review failed", sr.Stage)
case sr.State != api.ReviewStateDone:
return fmt.Sprintf("the %q review ended %s", sr.Stage, sr.State)
}
if sr.Result != nil {
f, _ := (*sr.Result)["findings"].([]any)
findings = append(findings, f...)
}
}
switch len(findings) {
case 0: