Match a fix to a delivered revision by what the gate says of its merge; keep #474's source catch-up at start (issues 1946, 1726)
This commit is contained in:
@@ -131,3 +131,45 @@ func TestANewerRevisionCoversTheOlderMergesOfItsRepositoryAsTheForgeSaysAncestry
|
||||
t.Fatalf("another repository's head covered it: %q", v.Delivery)
|
||||
}
|
||||
}
|
||||
|
||||
// A fix kept with only its merged flag (heard through `checks`, or kept before release 6) is matched to a delivered revision
|
||||
// by asking the delivery for its merge: the group and the commit it landed as.
|
||||
func TestAFixKeptWithoutItsMergeIsMatchedByAskingTheDeliveryForIt(t *testing.T) {
|
||||
h := newHarness(t)
|
||||
n := fixIssue(t, h, "mesh-catalog#40")
|
||||
// Kept as a fix the tracker heard merged and nothing more: no group, no commit, no repository.
|
||||
if _, err := h.change(n, Act{Op: "delivery", By: Seat}, func(i *Issue) error {
|
||||
at := time.Date(2026, 10, 24, 12, 0, 0, 0, time.UTC)
|
||||
i.Fixes = append(i.Fixes, Fix{PullRequest: "mesh-catalog#40", State: "published", Merged: true, MergedAt: &at, Since: at})
|
||||
return nil
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
asked := 0
|
||||
h.Deliveries = func(repository, number string) (Delivery, error) {
|
||||
asked++
|
||||
return Delivery{State: "merged", Merged: true, Repository: "novox/mesh-catalog", Group: "feat/r6", MergedAs: "9999999999990000"}, nil
|
||||
}
|
||||
viewSays(t, h, 20, "feat/r6", nil)
|
||||
if asked == 0 {
|
||||
t.Fatal("the delivery was not asked for the merge of a fix kept without it")
|
||||
}
|
||||
if v, _ := h.View(n); v.Delivery != "delivered to every machine it should reach" {
|
||||
t.Fatalf("%q", v.Delivery)
|
||||
}
|
||||
// What `checks` says is carried: group, commit and repository reach the fix when it is heard through the delivery.
|
||||
h2 := newHarness(t)
|
||||
m := h2.open(t, "x")
|
||||
h2.Deliveries = func(string, string) (Delivery, error) {
|
||||
return Delivery{State: "merged", Merged: true, Since: time.Date(2026, 10, 24, 12, 0, 0, 0, time.UTC), Repository: "novox/mesh-catalog",
|
||||
Group: "feat/q", MergedAs: "8888888888880000"}, nil
|
||||
}
|
||||
fixedAtFixing(t, h2, m, "mesh-catalog#41")
|
||||
if err := h2.OnMoved(stdio.Envelope{Body: []byte(`{"number":` + itoa(int(m)) + `}`)}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
f := fixOf(get(t, h2, m), "mesh-catalog#41")
|
||||
if f == nil || f.Group != "feat/q" || f.MergedAs != "8888888888880000" || f.Repository != "novox/mesh-catalog" {
|
||||
t.Fatalf("heard through checks the fix keeps %+v", f)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,6 +453,9 @@ func (t *Tracker) OnDelivered(e stdio.Envelope) error {
|
||||
for n, is := range all {
|
||||
for _, pr := range liveFixes(is) {
|
||||
f := fixOf(is, pr)
|
||||
if f != nil && f.Merged && !contains(is.Delivered, pr) && f.MergedAs == "" {
|
||||
t.fillMerge(n, f, pr)
|
||||
}
|
||||
if f == nil || !f.Merged || contains(is.Delivered, pr) || !(deliveredBy(f, body.Group, body.Heads) || t.coveredBy(f, body.Heads)) {
|
||||
continue
|
||||
}
|
||||
@@ -482,6 +485,40 @@ func (t *Tracker) OnDelivered(e stdio.Envelope) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// fillMerge learns what the gate says of the merge of a fix kept without it (heard through `checks`, or kept before release 6
|
||||
// with only its merged flag): the repository, the group and the commit its merge landed as, asked of the delivery. A delivery
|
||||
// that cannot be asked, or does not say, leaves the fix as it was; it is asked again at the next event. f is updated in place.
|
||||
func (t *Tracker) fillMerge(n uint64, f *Fix, pr string) {
|
||||
if t.Deliveries == nil {
|
||||
return
|
||||
}
|
||||
repo, number, _ := strings.Cut(pr, "#")
|
||||
d, err := t.Deliveries(repo, number)
|
||||
if err != nil {
|
||||
t.Logf("[mesh-issues] the merge of %s (issue %d) could not be asked of the delivery: %v", pr, n, err)
|
||||
return
|
||||
}
|
||||
if d.MergedAs == "" {
|
||||
return
|
||||
}
|
||||
if _, err := t.change(n, Act{Op: "delivery", By: Seat}, func(i *Issue) error {
|
||||
if g := fixOf(i, pr); g != nil {
|
||||
g.MergedAs, g.Group = d.MergedAs, d.Group
|
||||
if d.Repository != "" {
|
||||
g.Repository = d.Repository
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
t.Logf("[mesh-issues] the merge of %s (issue %d) could not be kept: %v", pr, n, err)
|
||||
return
|
||||
}
|
||||
f.MergedAs, f.Group = d.MergedAs, d.Group
|
||||
if d.Repository != "" {
|
||||
f.Repository = d.Repository
|
||||
}
|
||||
}
|
||||
|
||||
// busContains asks the forge's gitea_contains over the bus: whether commit is an ancestor of in, or it.
|
||||
func busContains(owner, repo, commit, in string) (bool, error) {
|
||||
raw, err := stdio.Ask("gitea.gitea_contains", map[string]any{"owner": owner, "repo": repo, "commit": commit, "in": in})
|
||||
@@ -568,11 +605,16 @@ type Delivery struct {
|
||||
Class string
|
||||
Opened *time.Time
|
||||
MergedAt *time.Time
|
||||
// Repository (owner/name), Group and MergedAs are what the gate says of the merge, which the view's `delivered` is matched by.
|
||||
Repository string
|
||||
Group string
|
||||
MergedAs string
|
||||
}
|
||||
|
||||
// heard is what a delivery answered, as a fix keeps it.
|
||||
func (d Delivery) heard(since time.Time) heardFix {
|
||||
return heardFix{State: d.State, Why: d.Why, Merged: d.Merged, At: since, Class: d.Class, Opened: d.Opened, MergedAt: d.MergedAt}
|
||||
return heardFix{State: d.State, Why: d.Why, Merged: d.Merged, At: since, Class: d.Class, Opened: d.Opened, MergedAt: d.MergedAt,
|
||||
Repository: d.Repository, Group: d.Group, MergedAs: d.MergedAs}
|
||||
}
|
||||
|
||||
// nonZero is a moment said, or nil for one not said.
|
||||
@@ -602,6 +644,8 @@ func busDeliveryState(owner string) DeliveryState {
|
||||
Class string `json:"class"`
|
||||
Opened *time.Time `json:"opened"`
|
||||
MergedAt *time.Time `json:"merged_at"`
|
||||
Group string `json:"group"`
|
||||
MergedAs string `json:"merged_as"`
|
||||
} `json:"delivery"`
|
||||
Pull struct {
|
||||
Merged bool `json:"merged"`
|
||||
@@ -611,7 +655,8 @@ func busDeliveryState(owner string) DeliveryState {
|
||||
return Delivery{}, fmt.Errorf("mesh-delivery's checks answered no delivery: %.200s", raw)
|
||||
}
|
||||
return Delivery{State: out.Delivery.State, Why: out.Delivery.Waits, Since: out.Delivery.Since.UTC(), Merged: out.Pull.Merged,
|
||||
Class: out.Delivery.Class, Opened: nonZero(out.Delivery.Opened), MergedAt: nonZero(out.Delivery.MergedAt)}, nil
|
||||
Class: out.Delivery.Class, Opened: nonZero(out.Delivery.Opened), MergedAt: nonZero(out.Delivery.MergedAt),
|
||||
Repository: strings.ToLower(owner + "/" + repository), Group: out.Delivery.Group, MergedAs: out.Delivery.MergedAs}, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user