diff --git a/modules/mesh-issues/cmd/mesh-issues/list_progress_test.go b/modules/mesh-issues/cmd/mesh-issues/list_progress_test.go index ef252169..844989f1 100644 --- a/modules/mesh-issues/cmd/mesh-issues/list_progress_test.go +++ b/modules/mesh-issues/cmd/mesh-issues/list_progress_test.go @@ -2,6 +2,7 @@ package main import ( "reflect" + "strings" "testing" "time" ) @@ -26,6 +27,22 @@ func TestListSaysWhenEachIssueMovedAndKeepsTheLinkedOnes(t *testing.T) { if _, err := h.Link(LinkAsk{Number: quiet, Kind: LinkDesign, Target: "03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md"}); err != nil { t.Fatal(err) } + // Issue 1781: a milestone or a commit link places the issue and moves nothing, nor keeps its worker current. + if _, err := h.milestoneSet("lead@shanks", MilestoneSetAsk{Design: 47, ID: "R6", Outcome: "x"}); err != nil { + t.Fatal(err) + } + h.fixing(t, noted) + worked, _ := h.Get(noted) + clock = clock.Add(time.Hour) + for _, l := range []LinkAsk{{Number: noted, Kind: LinkMilestone, Target: "47/R6"}, + {Number: noted, Kind: LinkCommit, Target: "mesh-catalog@" + strings.Repeat("a", 40)}} { + if _, err := h.link("seed@shanks", l); err != nil { + t.Fatal(err) + } + } + if after, _ := h.Get(noted); !after.Worker.Active.Equal(worked.Worker.Active) { + t.Fatalf("a milestone link kept the worker current: %v, was %v", after.Worker.Active, worked.Worker.Active) + } start := time.Date(2026, 10, 26, 12, 0, 0, 0, time.UTC) for _, c := range []struct { name string @@ -35,7 +52,7 @@ func TestListSaysWhenEachIssueMovedAndKeepsTheLinkedOnes(t *testing.T) { refuse bool }{ {"numbers say moved", ListAsk{Numbers: []uint64{quiet, noted, linked}}, []uint64{quiet, noted, linked}, - []time.Time{start.Add(2 * time.Hour), start.Add(time.Hour), start.Add(2 * time.Hour)}, false}, + []time.Time{start.Add(2 * time.Hour), start.Add(2 * time.Hour), start.Add(2 * time.Hour)}, false}, {"linked to a decision", ListAsk{Linked: "decision:0493"}, []uint64{linked}, nil, false}, {"linked to a design", ListAsk{Linked: " design:03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md"}, []uint64{quiet}, nil, false}, {"linked and numbers together", ListAsk{Linked: "decision:0493", Numbers: []uint64{quiet, noted}}, nil, nil, false}, diff --git a/modules/mesh-issues/cmd/mesh-issues/tracker.go b/modules/mesh-issues/cmd/mesh-issues/tracker.go index 2f06b304..03780639 100644 --- a/modules/mesh-issues/cmd/mesh-issues/tracker.go +++ b/modules/mesh-issues/cmd/mesh-issues/tracker.go @@ -675,7 +675,9 @@ func (t *Tracker) link(by string, a LinkAsk) (*Linked, error) { return fmt.Errorf("issue %d already has the %s link to %s", is.Number, kind, target) } is.Links = append(is.Links[:i:i], is.Links[i+1:]...) - touch(is, by, at) + if !placesOnly(kind) { + touch(is, by, at) + } return nil } } @@ -692,7 +694,9 @@ func (t *Tracker) link(by string, a LinkAsk) (*Linked, error) { return fmt.Errorf("issue %d has %d links, the most one issue keeps", is.Number, MostLinks) } is.Links = append(is.Links, Link{Kind: kind, Target: target, By: by, At: at}) - touch(is, by, at) + if !placesOnly(kind) { + touch(is, by, at) + } return nil }) if err != nil { @@ -768,7 +772,7 @@ type Row struct { } // lastMoved is when an issue last changed, as its own record says: the latest of its opening, its closing, its -// notes, its links, its worker's start and last act, its import and what the delivery last said of each fix. +// notes, its links but those that only place it, its worker's start and last act, its import and what the delivery last said of each fix. func lastMoved(is *Issue) time.Time { at := is.Opened later := func(t time.Time) { @@ -783,7 +787,9 @@ func lastMoved(is *Issue) time.Time { later(n.At) } for _, l := range is.Links { - later(l.At) + if !placesOnly(l.Kind) { + later(l.At) + } } if w := is.Worker; w != nil { later(w.Since) @@ -798,6 +804,10 @@ func lastMoved(is *Issue) time.Time { return at } +// placesOnly says a link of this kind only places the issue (its milestone) or names a commit that fixed it: no work +// on it, so it neither moves the issue nor keeps its worker current (issue 1781: the seed linked 188 issues at once). +func placesOnly(kind string) bool { return kind == LinkMilestone || kind == LinkCommit } + // checkLinked is a list's linked filter, kind:target, said the one way a link of that kind is kept. func checkLinked(s string) (kind, target string, err error) { k, t, ok := strings.Cut(strings.TrimSpace(s), ":")