Add auto-merge setting and merge now functionality

This commit is contained in:
2026-07-28 17:42:49 +02:00
parent 7511311297
commit 42dcceaf4b
10 changed files with 689 additions and 63 deletions

View File

@@ -33,6 +33,29 @@ type recordingPRService struct {
branchErr error
}
type recordingMergeService struct {
recordingService
id, head, method string
enabled bool
}
func (s *recordingMergeService) SetPullRequestAutoMerge(
_ context.Context, id, head, method string, enabled bool,
) (*AutoMergeRequest, error) {
s.id, s.head, s.method, s.enabled = id, head, method, enabled
if !enabled {
return nil, nil
}
return &AutoMergeRequest{MergeMethod: method, EnabledBy: "me", EnabledAt: time.Now()}, nil
}
func (s *recordingMergeService) MergePullRequest(
_ context.Context, id, head, method string,
) (PullRequestMergeResult, error) {
s.id, s.head, s.method = id, head, method
return PullRequestMergeResult{Merged: true, MergedAt: time.Now()}, nil
}
func (s *recordingPRService) UpdatePullRequest(
_ context.Context,
id string,
@@ -552,6 +575,70 @@ func TestWriteCapabilityGateExplainsCachedAndPermissionStates(t *testing.T) {
}
}
func TestDashboardCanToggleAutoMergeAndMergeReadyPR(t *testing.T) {
service := &recordingMergeService{}
m := NewApp(service, "o", "r", false, 50, time.Minute)
m.screen, m.loading, m.width, m.height = dashboardScreen, false, 100, 30
m.details = PRDetails{
PullRequest: PullRequest{
ID: "pr", Owner: "o", Repository: "r", RepoWithOwner: "o/r",
Number: 1, Title: "Ready",
},
HeadOID: "head", BaseRef: "main", Mergeable: "MERGEABLE",
ReviewDecision: "APPROVED", CheckState: "SUCCESS",
AllowedMergeMethods: []string{"SQUASH", "MERGE"},
Permissions: ViewerPermissions{CanEnableMerge: true},
}
updated, _ := m.Update(runeKey("a"))
m = updated.(App)
if m.writeMode != writeAutoMergeConfirm || m.mergeMethod != "SQUASH" {
t.Fatalf("auto-merge confirmation = mode %d method %q", m.writeMode, m.mergeMethod)
}
updated, command := m.Update(runeKey("y"))
m = updated.(App)
if command == nil || m.writeMode != writeAutoMergeBusy {
t.Fatalf("auto-merge submit = mode %d command %v", m.writeMode, command)
}
updated, _ = m.Update(command())
m = updated.(App)
if m.details.AutoMerge == nil || !service.enabled ||
service.id != "pr" || service.head != "head" || service.method != "SQUASH" {
t.Fatalf("auto-merge result = details %#v service %#v", m.details.AutoMerge, service)
}
updated, _ = m.Update(runeKey("M"))
m = updated.(App)
if m.writeMode != writeMergeNowConfirm {
t.Fatalf("merge confirmation mode = %d", m.writeMode)
}
updated, command = m.Update(runeKey("y"))
m = updated.(App)
updated, _ = m.Update(command())
m = updated.(App)
if !m.details.Merged || m.details.State != "MERGED" {
t.Fatalf("merged details = %#v", m.details)
}
}
func TestMergeNowIsGatedByCurrentRequirements(t *testing.T) {
service := &recordingMergeService{}
m := NewApp(service, "o", "r", false, 50, time.Minute)
m.screen, m.loading = dashboardScreen, false
m.details = PRDetails{
PullRequest: PullRequest{ID: "pr"},
HeadOID: "head", Mergeable: "MERGEABLE", CheckState: "FAILURE",
ReviewDecision: "APPROVED", AllowedMergeMethods: []string{"SQUASH"},
Requirements: MergeRequirements{RequiresStatusChecks: true},
}
updated, command := m.Update(runeKey("M"))
m = updated.(App)
if command != nil || m.writeMode != writeNone || m.err == nil ||
!strings.Contains(m.err.Error(), "status checks") {
t.Fatalf("failed-check merge gate = mode %d command %v error %v", m.writeMode, command, m.err)
}
}
func TestDashboardEditorUpdatesTitleBodyAndBaseBranch(t *testing.T) {
service := &recordingPRService{}
m := NewApp(service, "o", "r", false, 50, time.Second)