feat(worker): use the list base branch as worktree base and default merge target
This commit is contained in:
@@ -1092,6 +1092,74 @@ public class TaskMergeServiceTests : IDisposable
|
||||
Assert.False(Directory.Exists(wtCtx.WorktreePath));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetTargetsAsync_prefers_list_base_branch()
|
||||
{
|
||||
if (!GitRepoFixture.IsGitAvailable()) return;
|
||||
var repo = NewRepo();
|
||||
GitRepoFixture.RunGit(repo.RepoDir, "branch", "dev");
|
||||
var db = NewDb();
|
||||
var (list, task) = await SeedListAndTask(db, workingDir: repo.RepoDir, status: TaskStatus.Done);
|
||||
using (var ctx = db.CreateContext())
|
||||
await new ListRepository(ctx).SetConfigAsync(new ListConfigEntity { ListId = list.Id, BaseBranch = "dev" });
|
||||
|
||||
var (svc, _) = BuildService(db);
|
||||
var targets = await svc.GetTargetsAsync(task.Id, CancellationToken.None);
|
||||
|
||||
Assert.NotEqual("dev", await new GitService().GetCurrentBranchAsync(repo.RepoDir));
|
||||
Assert.Equal("dev", targets.DefaultBranch);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApproveAndMergeAsync_EmptyTarget_MergesIntoListBaseBranch()
|
||||
{
|
||||
if (!GitRepoFixture.IsGitAvailable()) return;
|
||||
var repo = NewRepo();
|
||||
GitRepoFixture.RunGit(repo.RepoDir, "branch", "dev");
|
||||
var original = await new GitService().GetCurrentBranchAsync(repo.RepoDir);
|
||||
var db = NewDb();
|
||||
var (list, task) = await SeedListAndTask(db, repo.RepoDir, TaskStatus.WaitingForReview);
|
||||
using (var ctx0 = db.CreateContext())
|
||||
await new ListRepository(ctx0).SetConfigAsync(new ListConfigEntity { ListId = list.Id, BaseBranch = "dev" });
|
||||
|
||||
var wtMgr = BuildWorktreeManager(db);
|
||||
var wtCtx = await wtMgr.CreateAsync(task, list, CancellationToken.None);
|
||||
_wtCleanups.Add((repo.RepoDir, wtCtx.WorktreePath));
|
||||
File.WriteAllText(Path.Combine(wtCtx.WorktreePath, "added.txt"), "new\n");
|
||||
await wtMgr.CommitIfChangedAsync(wtCtx, task, list, CancellationToken.None);
|
||||
|
||||
var (svc, _) = BuildService(db);
|
||||
var result = await svc.ApproveAndMergeAsync(task.Id, "", CancellationToken.None);
|
||||
|
||||
Assert.Equal(TaskMergeService.StatusMerged, result.Status);
|
||||
Assert.Contains("added.txt", GitRepoFixture.RunGit(repo.RepoDir, "ls-tree", "--name-only", "dev"));
|
||||
Assert.Equal(repo.BaseCommit, GitRepoFixture.RunGit(repo.RepoDir, "rev-parse", original).Trim());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MergeAsync_EmptyTarget_MergesIntoCheckedOutBranch()
|
||||
{
|
||||
// PlanningMergeOrchestrator.DrainAsync passes an empty target straight through — that used
|
||||
// to end in `git checkout ""` -> Blocked.
|
||||
if (!GitRepoFixture.IsGitAvailable()) return;
|
||||
var repo = NewRepo();
|
||||
var current = await new GitService().GetCurrentBranchAsync(repo.RepoDir);
|
||||
var db = NewDb();
|
||||
var (list, task) = await SeedListAndTask(db, repo.RepoDir, TaskStatus.WaitingForReview);
|
||||
|
||||
var wtMgr = BuildWorktreeManager(db);
|
||||
var wtCtx = await wtMgr.CreateAsync(task, list, CancellationToken.None);
|
||||
_wtCleanups.Add((repo.RepoDir, wtCtx.WorktreePath));
|
||||
File.WriteAllText(Path.Combine(wtCtx.WorktreePath, "added.txt"), "new\n");
|
||||
await wtMgr.CommitIfChangedAsync(wtCtx, task, list, CancellationToken.None);
|
||||
|
||||
var (svc, _) = BuildService(db);
|
||||
var result = await svc.MergeAsync(task.Id, "", false, "msg", CancellationToken.None);
|
||||
|
||||
Assert.Equal(TaskMergeService.StatusMerged, result.Status);
|
||||
Assert.Contains("added.txt", GitRepoFixture.RunGit(repo.RepoDir, "ls-tree", "--name-only", current));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApproveAndMergeAsync_Conflict_LeavesTaskWaitingForReview()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user