Word a delivery that needs its author's new head as its author's, with no Stop (ADR 0505 §5)
mesh/repo-check head b7d03b68974d merged into trunk 8f2d22db0caa beside mesh-catalog#444@09e749bc — pass: its merge-check.sh passed
mesh/merge-gate head b7d03b68974d merged into trunk 8f2d22db0caa — pass: group feat/quiet-deliveries composed: every machine composes with the change as it…
mesh/check checking b7d03b68974d on 8f2d22db0caa
mesh/delivery delivered
mesh/delivery-group group feat/quiet-deliveries delivered: every member is delivered
mesh/repo-check head b7d03b68974d merged into trunk 8f2d22db0caa beside mesh-catalog#444@09e749bc — pass: its merge-check.sh passed
mesh/merge-gate head b7d03b68974d merged into trunk 8f2d22db0caa — pass: group feat/quiet-deliveries composed: every machine composes with the change as it…
mesh/check checking b7d03b68974d on 8f2d22db0caa
mesh/delivery delivered
mesh/delivery-group group feat/quiet-deliveries delivered: every member is delivered
This commit is contained in:
@@ -58,8 +58,17 @@ type stalledLine struct {
|
||||
// Severity is "urgent" for a group held or half merged and a refused member (novox/hq issues 1275, 1278); empty
|
||||
// or anything else is a warning, as before.
|
||||
Severity string `json:"severity,omitempty"`
|
||||
// Needs is "new-head" for a delivery whose cure is its author's new head (novox/hq ADR 0505 §5), Author that author
|
||||
// as the operator reads it ("the author of feat/x", with the session that pushed it when its pull request names one)
|
||||
// and Branch its branch. A mesh-delivery from before says none, and the words are as before.
|
||||
Needs string `json:"needs,omitempty"`
|
||||
Author string `json:"author,omitempty"`
|
||||
Branch string `json:"branch,omitempty"`
|
||||
}
|
||||
|
||||
// needsNewHead is what a stalled line needs when its cure is its author's new head (ADR 0505 §5).
|
||||
const needsNewHead = "new-head"
|
||||
|
||||
// severity is the condition's severity a stalled line asks: urgent when it says so, a warning otherwise.
|
||||
func (l stalledLine) severity() conditions.Severity {
|
||||
if l.Severity == string(conditions.Urgent) {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/novox/mesh-controller/internal/conditions"
|
||||
)
|
||||
|
||||
// novox/hq ADR 0505 §5: a delivery whose cure is its author's new head reaches the operator in words that name its
|
||||
// author and say a new head is needed, offer no Stop and never call it the operator's; the line as mesh-delivery-gate
|
||||
// says it (ready.go readyLines: needs "new-head", author, branch).
|
||||
func TestADeliveryThatNeedsANewHeadNamesItsAuthorAndOffersNoStop(t *testing.T) {
|
||||
l := stalledLine{ID: "novox/mesh-controller@499ff5c21861", Number: 432, State: "rejected", For: "2h1m0s", Bound: "2h0m0s",
|
||||
H2: "none: a new head from its author, or a recheck that passes", Needs: needsNewHead,
|
||||
Author: "the author of feat/quiet-deliveries (quiet-deliveries on shanks)", Branch: "feat/quiet-deliveries",
|
||||
Says: "novox/mesh-controller#432 passed its checks at 499ff5c21861 and is not merged: a conflict"}
|
||||
o := stalledObservations([]stalledLine{l})[0]
|
||||
for _, words := range []string{o.Headline, o.Explanation, o.Resolved, o.Needs} {
|
||||
if why, ok := conditions.Plain(words); !ok {
|
||||
t.Errorf("%q is not plain: %s", words, why)
|
||||
}
|
||||
for _, never := range []string{"stop it", "operator's"} {
|
||||
if strings.Contains(words, never) {
|
||||
t.Errorf("%q says %q", words, never)
|
||||
}
|
||||
}
|
||||
}
|
||||
if o.Headline != "Pull request 432 of mesh-controller needs a new head from its author" ||
|
||||
!strings.Contains(o.Explanation, "until the author of feat/quiet-deliveries (quiet-deliveries on shanks) pushes a new head") ||
|
||||
!strings.Contains(o.Explanation, "for 2 hours") || len(o.Actions) != 0 ||
|
||||
o.Needs != "ask the author of feat/quiet-deliveries (quiet-deliveries on shanks) for a new head." {
|
||||
t.Fatalf("words: %q / %q / %q / %v", o.Headline, o.Explanation, o.Needs, o.Actions)
|
||||
}
|
||||
// A branch in code is not said; the author is then "its author".
|
||||
l.Author = "the author of fix/a1b2c3d4e5f6"
|
||||
if o := stalledObservations([]stalledLine{l})[0]; !strings.Contains(o.Needs, "ask its author") {
|
||||
t.Fatalf("a dotted branch was said: %q", o.Needs)
|
||||
}
|
||||
}
|
||||
@@ -966,6 +966,9 @@ func stalledWords(l stalledLine, o conditions.Observation) (headline, explanatio
|
||||
if l.State == "unanswered" {
|
||||
return unansweredWords(l, o)
|
||||
}
|
||||
if l.Needs == needsNewHead {
|
||||
return newHeadWords(l, name)
|
||||
}
|
||||
held := l.State
|
||||
if held == "" {
|
||||
held = "held"
|
||||
@@ -999,6 +1002,29 @@ func stalledWords(l stalledLine, o conditions.Observation) (headline, explanatio
|
||||
fmt.Sprintf("Delivery of %s is no longer %s", name, held), needs, actions
|
||||
}
|
||||
|
||||
// newHeadWords are the words of a delivery whose cure is its author's new head (novox/hq ADR 0505 §5): it names the
|
||||
// author and says a new head is needed; it offers no Stop and never calls it the operator's, because the operator
|
||||
// hears of it only once the author's own watch has failed, after two hours with no new head.
|
||||
func newHeadWords(l stalledLine, name string) (headline, explanation, resolved, needs string, actions []conditions.Action) {
|
||||
pull := "A pull request of " + name
|
||||
if l.Number > 0 {
|
||||
pull = fmt.Sprintf("Pull request %d of %s", l.Number, name)
|
||||
}
|
||||
author := l.Author
|
||||
if _, plain := conditions.Plain(author); !plain {
|
||||
author = "its author" // a branch named in code (a dotted name, a number) is not said
|
||||
}
|
||||
long := "for a long time"
|
||||
if d, err := time.ParseDuration(l.For); err == nil {
|
||||
long = "for " + humanDuration(d)
|
||||
}
|
||||
return pull + " needs a new head from its author",
|
||||
fmt.Sprintf("%s cannot merge until %s pushes a new head: its check failed after its Approve, and no new head "+
|
||||
"came %s.", pull, author, long),
|
||||
pull + " has a new head, or is closed",
|
||||
"ask " + author + " for a new head.", nil
|
||||
}
|
||||
|
||||
// stoppedNeeds is what ends a delivery that is already stopped, from the stalled line's healer words ("none: a
|
||||
// merge that delivers its modules ends it — the operator's"): the part that says what ends it.
|
||||
func stoppedNeeds(l stalledLine) string {
|
||||
|
||||
Reference in New Issue
Block a user