diff --git a/modules/mesh-delivery/cmd/mesh-delivery/ready.go b/modules/mesh-delivery/cmd/mesh-delivery/ready.go index f6f98672..fa36708a 100644 --- a/modules/mesh-delivery/cmd/mesh-delivery/ready.go +++ b/modules/mesh-delivery/cmd/mesh-delivery/ready.go @@ -69,8 +69,14 @@ type ReadyRun struct { Merged *time.Time `json:"merged,omitempty"` // Failed is why it is not merged and will not be on this head: its check failed. Said once on the pull request. Failed string `json:"failed,omitempty"` + // OtherBase is the branch its pull request merges into when that is not main: never merged here, said once on the + // pull request (novox/hq ADR 0398 §4, issue 948). + OtherBase string `json:"other_base,omitempty"` } +// MergeBranch is the one branch this owner merges into (novox/hq ADR 0398 §4): a merge into any other is its author's. +const MergeBranch = "main" + // mergedBy is who a merge this owner made on a ready mark is said to be by, in its transitions. func (r *ReadyRun) mergedBy() string { if r == nil || r.Merged == nil { @@ -185,6 +191,18 @@ func (h *Holder) readyAsks(now time.Time) []func() { } continue } + if p.Base != MergeBranch { + if r.OtherBase != p.Base { + r.OtherBase = p.Base + h.Logf("[mesh-delivery] %s is marked ready and not merged: it merges into %s, not %s", d.ID, p.Base, MergeBranch) + h.keep(d) + asks = append(asks, h.sayOn(d, fmt.Sprintf("mesh-delivery: **not merged.** This pull request is marked ready "+ + "at %s, and it merges into %s. Only a merge into %s is this owner's; a merge into another branch is its "+ + "author's (novox/hq ADR 0398 §4). The mark stays.", mark.Head, p.Base, MergeBranch))) + } + continue + } + r.OtherBase = "" r.Failed = "" waits := h.readyWaits(d) if waits != r.Waits { diff --git a/modules/mesh-delivery/cmd/mesh-delivery/ready_test.go b/modules/mesh-delivery/cmd/mesh-delivery/ready_test.go index e818e9b1..565f08bb 100644 --- a/modules/mesh-delivery/cmd/mesh-delivery/ready_test.go +++ b/modules/mesh-delivery/cmd/mesh-delivery/ready_test.go @@ -197,3 +197,31 @@ func TestAGroupMergesItsMarkedMembersInOrderOnlyOnceComposed(t *testing.T) { t.Fatalf("after the first member merged, the next was not: %v", w.forge.merges) } } + +// **A merge into another branch than main is its author's** (novox/hq ADR 0398 §4, issue 948): a ready mark on a pull +// request whose base is not main is never merged by this owner; it says so once on the pull request and leaves the mark. +func TestAMarkedGreenPullRequestIntoAnotherBranchIsNotMergedAndSaidOnce(t *testing.T) { + w := newWorld(t) + p := pr("novox/app", 7, readyHead, "feat/x", "src/a.go") + p.Base = "release/x" + w.h.PullUpdated(p) + w.h.Checked(judgedAt("novox/app", 7, readyHead, "pass", "t1t1t1t1t1t1")) + open := markedPull("novox/app", 7, readyHead, readyHead) + open.Base = "release/x" + w.forge.open = []OpenPull{open} + for range 3 { + w.h.SeeOpenPulls() + w.settleAll() + w.later(2 * time.Minute) + } + if len(w.forge.merges) != 0 { + t.Fatalf("a pull request into release/x was merged: %v", w.forge.merges) + } + if len(w.forge.comments) != 1 || !strings.Contains(w.forge.comments[0], "another branch") || + !strings.Contains(w.forge.comments[0], "0398") { + t.Fatalf("not said exactly once on the pull request: %v", w.forge.comments) + } + if len(w.forge.unlabels) != 0 { + t.Fatalf("the mark was taken off: %v", w.forge.unlabels) + } +}