fix(merge): apply the verify gate to worktree-less approvals and report it everywhere
ApproveAndMergeAsync short-circuits to Done whenever a task has no active worktree -- which is exactly how a list-handler task works, since it commits straight into the list working dir. The verify command was skipped for the run that lands the most on the target branch at once; the loaded command was even discarded at the destructuring. It now runs under the same per-repo gate as the merge path before the task may reach Done. The two merge entry points that did not know verify_failed reported it as "Unknown status: verify_failed" (merge modal, dropping the command output) and as a generic Failed (worktrees batch, claiming the merge never happened).
This commit is contained in:
@@ -714,6 +714,46 @@ public class TaskMergeServiceTests : IDisposable
|
||||
Assert.Equal(TaskStatus.Done, updated!.Status);
|
||||
}
|
||||
|
||||
// A list-handler task owns no worktree -- it commits straight into the list's working dir --
|
||||
// so the approve path short-circuits past the merge. The verify gate must still apply, or the
|
||||
// run that lands the most on the target branch would be the one run nothing checks.
|
||||
[Fact]
|
||||
public async Task ApproveAndMergeAsync_NoWorktreeAndVerifyFails_StaysOutOfDone()
|
||||
{
|
||||
var db = NewDb();
|
||||
var (list, task) = await SeedListAndTask(db, workingDir: "/tmp", status: TaskStatus.WaitingForReview);
|
||||
await SeedVerifyCommand(db, list.Id, "dotnet test");
|
||||
var fakeVerify = new FakeVerifyCommandRunner { Result = new VerifyCommandResult(1, false, "2 failed") };
|
||||
var (svc, _) = BuildService(db, fakeVerify);
|
||||
|
||||
var result = await svc.ApproveAndMergeAsync(task.Id, "main", CancellationToken.None);
|
||||
|
||||
Assert.Equal(TaskMergeService.StatusVerifyFailed, result.Status);
|
||||
Assert.Contains("2 failed", result.ErrorMessage ?? "");
|
||||
Assert.Equal("/tmp", fakeVerify.CapturedWorkingDir);
|
||||
using var ctx = db.CreateContext();
|
||||
var updated = await new TaskRepository(ctx).GetByIdAsync(task.Id);
|
||||
Assert.Equal(TaskStatus.WaitingForReview, updated!.Status);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApproveAndMergeAsync_NoWorktreeAndVerifyPasses_MarksDone()
|
||||
{
|
||||
var db = NewDb();
|
||||
var (list, task) = await SeedListAndTask(db, workingDir: "/tmp", status: TaskStatus.WaitingForReview);
|
||||
await SeedVerifyCommand(db, list.Id, "dotnet test");
|
||||
var fakeVerify = new FakeVerifyCommandRunner { Result = new VerifyCommandResult(0, false, "ok") };
|
||||
var (svc, _) = BuildService(db, fakeVerify);
|
||||
|
||||
var result = await svc.ApproveAndMergeAsync(task.Id, "main", CancellationToken.None);
|
||||
|
||||
Assert.Equal(TaskMergeService.StatusMerged, result.Status);
|
||||
Assert.Equal("dotnet test", fakeVerify.CapturedCommand);
|
||||
using var ctx = db.CreateContext();
|
||||
var updated = await new TaskRepository(ctx).GetByIdAsync(task.Id);
|
||||
Assert.Equal(TaskStatus.Done, updated!.Status);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApproveAndMergeAsync_NoVerifyCommandConfigured_NeverInvokesRunnerAndMarksDone()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user