Record merge progress durably and finish pushed merges at startup

This commit is contained in:
Ian Gulliver
2026-10-16 13:01:17 -07:00
parent 51dfbf78a0
commit d9e0498d10
6 changed files with 211 additions and 42 deletions
+57 -4
View File
@@ -452,6 +452,10 @@ ALTER TABLE tasks ADD COLUMN finalizing TEXT NOT NULL DEFAULT '';
ALTER TABLE tasks ADD COLUMN state TEXT NOT NULL DEFAULT '';
ALTER TABLE tasks ADD COLUMN review_requests INTEGER NOT NULL DEFAULT 0;
UPDATE tasks SET state = ` + taskStateExpr + `;
`}, {"add-task-finalizing-commit", `
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;
`}}
const (
@@ -874,7 +878,7 @@ func (s *Store) TakeMergingBy(ctx context.Context, id string) (string, error) {
func (s *Store) ClearFinalizing(ctx context.Context, id string) error {
return s.write(ctx, func(tx *sql.Tx, emit emitFunc) error {
projectID := ""
err := tx.QueryRowContext(ctx, `UPDATE tasks SET finalizing = '' WHERE id = ? AND finalizing != '' RETURNING project_id`, id).Scan(&projectID)
err := tx.QueryRowContext(ctx, `UPDATE tasks SET finalizing = '', finalizing_commit = '', finalizing_notes = '', finalizing_unchanged = 0 WHERE id = ? AND finalizing != '' RETURNING project_id`, id).Scan(&projectID)
if errors.Is(err, sql.ErrNoRows) {
return nil
}
@@ -885,8 +889,57 @@ func (s *Store) ClearFinalizing(ctx context.Context, id string) error {
})
}
func (s *Store) FinalizingTasks(ctx context.Context) ([]api.Task, error) {
return s.queryTasks(ctx, `SELECT `+taskColumns+` FROM tasks WHERE status = ? AND finalizing != ''`, string(api.TaskStatusActive))
func (s *Store) SetFinalizingCommit(ctx context.Context, id, commit, notes string) error {
return s.setFinalizing(ctx, id, commit, notes, false)
}
func (s *Store) SetFinalizingUnchanged(ctx context.Context, id string) error {
return s.setFinalizing(ctx, id, "", "", true)
}
func (s *Store) setFinalizing(ctx context.Context, id, commit, notes string, unchanged bool) error {
return s.write(ctx, func(tx *sql.Tx, emit emitFunc) error {
res, err := tx.ExecContext(ctx, `UPDATE tasks SET finalizing_commit = ?, finalizing_notes = ?, finalizing_unchanged = ? WHERE id = ? AND status = ? AND finalizing != ''`,
commit, notes, unchanged, id, string(api.TaskStatusActive))
if err != nil {
return err
}
n, err := res.RowsAffected()
if err != nil {
return err
}
if n == 0 {
return ErrNotFound
}
return nil
})
}
type FinalizingMerge struct {
Task api.Task
By string
Commit string
Notes string
Unchanged bool
}
func (s *Store) FinalizingMerges(ctx context.Context) ([]FinalizingMerge, error) {
rows, err := s.db.QueryContext(ctx, `SELECT `+taskColumns+`, finalizing, finalizing_commit, finalizing_notes, finalizing_unchanged FROM tasks WHERE status = ? AND finalizing != ''`, string(api.TaskStatusActive))
if err != nil {
return nil, err
}
defer rows.Close()
merges := []FinalizingMerge{}
for rows.Next() {
f := FinalizingMerge{}
f.Task, err = scanTask(trailingScanner{rows, []any{&f.By, &f.Commit, &f.Notes, &f.Unchanged}})
if err != nil {
return nil, err
}
merges = append(merges, f)
}
return merges, rows.Err()
}
func (s *Store) MergingTasks(ctx context.Context) ([]api.Task, error) {
@@ -1107,7 +1160,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 = '' 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 WHERE id = ? AND status = ?`,
string(status), now(), commit, id, string(api.TaskStatusActive))
if err != nil {
return err