Offer "After review" in the Merge dialog while a review runs
This commit is contained in:
@@ -76,7 +76,7 @@ func (s *Store) RequestDiscard(ctx context.Context, taskID, actor string) (Disca
|
||||
return ErrHasSubtasks
|
||||
}
|
||||
state = DiscardHeld
|
||||
_, err = tx.ExecContext(ctx, `UPDATE tasks SET discard_state = ?, discarding_by = ?, discard_session = '', merge_queued_by = '', merge_queued_at = '' WHERE id = ?`,
|
||||
_, err = tx.ExecContext(ctx, `UPDATE tasks SET discard_state = ?, discarding_by = ?, discard_session = '', merge_queued_by = '', merge_queued_at = '', merge_after_review_by = '', merge_after_review_id = '', merge_after_review_target = '' WHERE id = ?`,
|
||||
string(DiscardHeld), actor, taskID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+94
-3
@@ -456,6 +456,10 @@ UPDATE tasks SET state = ` + taskStateExpr + `;
|
||||
ALTER TABLE tasks ADD COLUMN finalizing_commit TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE tasks ADD COLUMN finalizing_notes TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE tasks ADD COLUMN finalizing_unchanged INTEGER NOT NULL DEFAULT 0;
|
||||
`}, {"add-task-merge-after-review", `
|
||||
ALTER TABLE tasks ADD COLUMN merge_after_review_by TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE tasks ADD COLUMN merge_after_review_id TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE tasks ADD COLUMN merge_after_review_target TEXT NOT NULL DEFAULT '';
|
||||
`}}
|
||||
|
||||
const (
|
||||
@@ -1082,6 +1086,93 @@ func (s *Store) TakeQueuedMerge(ctx context.Context, id string) (string, error)
|
||||
return login, err
|
||||
}
|
||||
|
||||
type MergeAfterReview struct {
|
||||
By string
|
||||
ReviewID string
|
||||
Target api.MergeTaskJSONBodyTarget
|
||||
}
|
||||
|
||||
func (s *Store) SetMergeAfterReview(ctx context.Context, id string, mar MergeAfterReview) error {
|
||||
return s.write(ctx, func(tx *sql.Tx, emit emitFunc) error {
|
||||
projectID := ""
|
||||
snapshotN := 0
|
||||
err := tx.QueryRowContext(ctx, `
|
||||
UPDATE tasks SET merge_after_review_by = ?, merge_after_review_id = ?, merge_after_review_target = ?
|
||||
WHERE id = ? AND status = ? AND discard_state = '' AND merging_by = '' AND finalizing = '' AND merge_queued_by = '' AND parent_merge_by = ''
|
||||
AND EXISTS (SELECT 1 FROM reviews WHERE reviews.id = ? AND reviews.task_id = tasks.id AND reviews.state = ?)
|
||||
RETURNING project_id, (SELECT snapshot_n FROM reviews WHERE reviews.id = ?)`,
|
||||
mar.By, mar.ReviewID, string(mar.Target), id, string(api.TaskStatusActive), mar.ReviewID, string(api.ReviewStateRunning), mar.ReviewID).Scan(&projectID, &snapshotN)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return ErrNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return emit(api.Event{Kind: "task.merge_after_review", ProjectId: &projectID, TaskId: &id, Actor: mar.By, Payload: map[string]any{"id": id, "review_id": mar.ReviewID, "snapshot_n": snapshotN, "target": string(mar.Target)}})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Store) CancelMergeAfterReview(ctx context.Context, id, actor string) error {
|
||||
return s.write(ctx, func(tx *sql.Tx, emit emitFunc) error {
|
||||
projectID := ""
|
||||
err := tx.QueryRowContext(ctx, `UPDATE tasks SET merge_after_review_by = '', merge_after_review_id = '', merge_after_review_target = '' WHERE id = ? AND merge_after_review_by != '' RETURNING project_id`, id).Scan(&projectID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return ErrNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return emit(api.Event{Kind: "task.merge_after_review_cancelled", ProjectId: &projectID, TaskId: &id, Actor: actor, Payload: map[string]any{"id": id}})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Store) FinishedMergeAfterReviews(ctx context.Context) ([]string, error) {
|
||||
rows, err := s.db.QueryContext(ctx, `
|
||||
SELECT tasks.merge_after_review_id FROM tasks JOIN reviews ON reviews.id = tasks.merge_after_review_id
|
||||
WHERE tasks.merge_after_review_by != '' AND reviews.state != ?`, string(api.ReviewStateRunning))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
ids := []string{}
|
||||
for rows.Next() {
|
||||
id := ""
|
||||
err = rows.Scan(&id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ids = append(ids, id)
|
||||
}
|
||||
return ids, rows.Err()
|
||||
}
|
||||
|
||||
func (s *Store) TakeMergeAfterReview(ctx context.Context, id, reviewID string) (MergeAfterReview, error) {
|
||||
mar := MergeAfterReview{}
|
||||
err := s.write(ctx, func(tx *sql.Tx, emit emitFunc) error {
|
||||
projectID, target := "", ""
|
||||
err := tx.QueryRowContext(ctx, `SELECT project_id, merge_after_review_by, merge_after_review_id, merge_after_review_target FROM tasks WHERE id = ?`, id).
|
||||
Scan(&projectID, &mar.By, &mar.ReviewID, &target)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return ErrNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mar.Target = api.MergeTaskJSONBodyTarget(target)
|
||||
if mar.By == "" || (reviewID != "" && mar.ReviewID != reviewID) {
|
||||
mar = MergeAfterReview{}
|
||||
return nil
|
||||
}
|
||||
_, err = tx.ExecContext(ctx, `UPDATE tasks SET merge_after_review_by = '', merge_after_review_id = '', merge_after_review_target = '' WHERE id = ?`, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return emit(api.Event{Kind: "task.merge_after_review_ended", ProjectId: &projectID, TaskId: &id, Actor: "byre", Payload: map[string]any{"id": id}})
|
||||
})
|
||||
return mar, err
|
||||
}
|
||||
|
||||
func (s *Store) SetTaskSummary(ctx context.Context, id, summary, actor string) error {
|
||||
return s.write(ctx, func(tx *sql.Tx, emit emitFunc) error {
|
||||
projectID := ""
|
||||
@@ -1160,7 +1251,7 @@ func (s *Store) DiscardTask(ctx context.Context, id, actor string) (api.Task, er
|
||||
|
||||
func (s *Store) closeTask(ctx context.Context, id string, status api.TaskStatus, commit, actor, kind string, payload map[string]any) (api.Task, error) {
|
||||
err := s.write(ctx, func(tx *sql.Tx, emit emitFunc) error {
|
||||
res, err := tx.ExecContext(ctx, `UPDATE tasks SET status = ?, closed_at = ?, merge_commit = ?, finalizing = '', finalizing_commit = '', finalizing_notes = '', finalizing_unchanged = 0 WHERE id = ? AND status = ?`,
|
||||
res, err := tx.ExecContext(ctx, `UPDATE tasks SET status = ?, closed_at = ?, merge_commit = ?, finalizing = '', finalizing_commit = '', finalizing_notes = '', finalizing_unchanged = 0, merge_after_review_by = '', merge_after_review_id = '', merge_after_review_target = '' WHERE id = ? AND status = ?`,
|
||||
string(status), now(), commit, id, string(api.TaskStatusActive))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -1749,7 +1840,7 @@ func (s *Store) ClearReviewRequests(ctx context.Context) error {
|
||||
|
||||
const projectColumns = `id, name, repo_path, default_branch, remote, created_by, created_at`
|
||||
|
||||
const taskColumns = `id, project_id, title, merge_title, branch, worktree_path, base_ref, port_base, color, status, created_by, created_at, closed_at, merge_commit, todo_item, forked_from, forked_at, merge_queued_at, workflow_name, workflow_run, workflow_stage, parent_task_id, parent_merge_by, state, merging_by != '' OR finalizing != '', discard_state != '' AND status = 'active', (SELECT coalesce(max(seq), 0) FROM events WHERE events.task_id = tasks.id AND kind = 'turn.ended' AND json_extract(payload, '$.summary') = 1)`
|
||||
const taskColumns = `id, project_id, title, merge_title, branch, worktree_path, base_ref, port_base, color, status, created_by, created_at, closed_at, merge_commit, todo_item, forked_from, forked_at, merge_queued_at, workflow_name, workflow_run, workflow_stage, parent_task_id, parent_merge_by, merge_after_review_by != '', state, merging_by != '' OR finalizing != '', discard_state != '' AND status = 'active', (SELECT coalesce(max(seq), 0) FROM events WHERE events.task_id = tasks.id AND kind = 'turn.ended' AND json_extract(payload, '$.summary') = 1)`
|
||||
|
||||
const sessionColumns = `id, coalesce(task_id, ''), owner, vendor, model, vendor_session_id, state, role, created_by, created_at, forked_from, forked_at`
|
||||
|
||||
@@ -1784,7 +1875,7 @@ func scanTask(row scanner) (api.Task, error) {
|
||||
parentTaskID := ""
|
||||
parentMergeBy := ""
|
||||
taskState := ""
|
||||
err := row.Scan(&t.Id, &t.ProjectId, &t.Title, &t.MergeTitle, &t.Branch, &t.WorktreePath, &t.BaseRef, &t.PortBase, &t.Color, &status, &t.CreatedBy, &createdAt, &closedAt, &mergeCommit, &todoItem, &forkedFrom, &forkedAt, &mergeQueuedAt, &workflowName, &workflowRun, &workflowStage, &parentTaskID, &parentMergeBy, &taskState, &t.Merging, &t.Discarding, &t.SummarySeq)
|
||||
err := row.Scan(&t.Id, &t.ProjectId, &t.Title, &t.MergeTitle, &t.Branch, &t.WorktreePath, &t.BaseRef, &t.PortBase, &t.Color, &status, &t.CreatedBy, &createdAt, &closedAt, &mergeCommit, &todoItem, &forkedFrom, &forkedAt, &mergeQueuedAt, &workflowName, &workflowRun, &workflowStage, &parentTaskID, &parentMergeBy, &t.MergeAfterReview, &taskState, &t.Merging, &t.Discarding, &t.SummarySeq)
|
||||
if err != nil {
|
||||
return t, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user