mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery superseded: a newer delivery to the same trunk took over its walk
mesh/delivery-group group fix/313-retire-adopted-history stopped: a member was stopped
121 lines
7.1 KiB
Go
121 lines
7.1 KiB
Go
package catalogue
|
|
|
|
// The delivery's owner (novox/hq ADR 0239, to-be 47): one holder for the mesh, the module mesh-delivery,
|
|
// which owns a delivery — one commit in one repository, from its pull request's head to every machine —
|
|
// and a delivery group, and asks the controller for every act. A seat of the mesh's own, so the role has
|
|
// one name whoever holds it, and the controller can tell whether anything holds it: while nothing does,
|
|
// the controller starts every walk itself, as it did before there was a delivery to own.
|
|
|
|
// DeliverySeat is the seat mesh-delivery holds.
|
|
const DeliverySeat = "mesh-delivery"
|
|
|
|
// deliveryVerbs are the delivery seat's tools: six that read, and the acts of a person and of healer H2.
|
|
func deliveryVerbs() []Verb {
|
|
return []Verb{
|
|
{Name: "deliveries", Description: "Every delivery not final, and those that ended in the last day, one line " +
|
|
"each: its id (owner/repository@commit), its state, its group, what it waits for and since when. Narrowed " +
|
|
"by state, repository or group.",
|
|
Input: schema(map[string]string{"state": "one state, e.g. delivering or held",
|
|
"repository": "owner/repository", "group": "a group's id (its branch name)",
|
|
"all": "\"true\": the final ones of the last thirty days too"}, nil, "all")},
|
|
{Name: "show", Description: "One delivery or group whole: its delivery plan (what it builds, what each " +
|
|
"machine receives, what is not an ordinary send), every transition with when and why, the machine " +
|
|
"steps of its walk, its group and its order.",
|
|
Input: schema(map[string]string{"id": "a delivery's id, or a group's"}, []string{"id"})},
|
|
{Name: "groups", Description: "Every delivery group: its members in order, why each pair is ordered " +
|
|
"(declared, built by, version skew, engine before controller, by name), its composed check and its " +
|
|
"state, derived from its members.",
|
|
Input: schema(map[string]string{"all": "\"true\": the groups that ended too"}, nil, "all")},
|
|
{Name: "what-if", Description: "The delivery plan a change would have, asked of the controller's planner " +
|
|
"and kept nowhere: the modules it moves and their dependents in tiers, what each machine would receive, " +
|
|
"the steps that are not an ordinary send.",
|
|
Input: schema(map[string]string{"repository": "owner/repository",
|
|
"paths": "the files it changes, comma-separated, from the repository's root",
|
|
"base": "the branch it merges into (default main)"}, []string{"repository", "paths"})},
|
|
{Name: "checks", Description: "What the mesh's checks said of a pull request's head or of one commit: each " +
|
|
"of the commit's mesh statuses (mesh/merge-gate, mesh/repo-check, mesh/delivery, …) with its state, " +
|
|
"description and when it was set; the merge check's full verdict as the controller said it — each " +
|
|
"layer's summary, the machine that ran it, when, its build id and its report; and whether the branch's " +
|
|
"protection would let it merge, every required status being success.",
|
|
Input: schema(map[string]string{"repository": "owner/repository",
|
|
"number": "a pull request's number: its head is read",
|
|
"commit": "a commit's sha, or the start of one, instead of a pull request"}, []string{"repository"}),
|
|
// Added after the seat's first holder shipped: optional until mesh-delivery serves it everywhere.
|
|
Optional: true},
|
|
{Name: "table", Description: "The state table every delivery runs by: each transition with its guard, " +
|
|
"each state's bound and what healer H2 may do once it has passed; and the machine steps' table.",
|
|
Input: schema(map[string]string{}, nil)},
|
|
{Name: "stalled", Description: "Every delivery held past its state's bound, with the transition the table " +
|
|
"lets healer H2 take for it, or none.",
|
|
Input: schema(map[string]string{}, nil)},
|
|
{Name: "recheck", Description: "Check a rejected or ready delivery again: it goes back to proposed and the " +
|
|
"controller is asked for its check. With why.",
|
|
Input: schema(map[string]string{"id": "the delivery's id", "why": "why, kept with the transition"},
|
|
[]string{"id", "why"})},
|
|
{Name: "release", Description: "A person's word that a held delivery goes on: it starts delivering. With why.",
|
|
Input: schema(map[string]string{"id": "the delivery's id", "why": "why, kept with the transition"},
|
|
[]string{"id", "why"})},
|
|
{Name: "stop", Description: "Stop a delivery that is not final, with why; its walk is ended through the " +
|
|
"controller, and in a group every member after it is stopped too, naming it.",
|
|
Input: schema(map[string]string{"id": "the delivery's id", "why": "why, kept with the transition"},
|
|
[]string{"id", "why"})},
|
|
{Name: "close", Description: "Healer H2's verb: take the one transition the table names for a delivery held " +
|
|
"past its bound. Refused for any other.",
|
|
Input: schema(map[string]string{"id": "the delivery's id", "why": "the condition it answers"},
|
|
[]string{"id", "why"})},
|
|
{Name: "retire-history", Description: "Retire held deliveries that are history, on a person's word, with " +
|
|
"why: each made from the forge's word for a merge on the trunk heard long after it happened — replayed " +
|
|
"when the holder first held the seat — with no walk of it open. Never released, delivered or put back: " +
|
|
"retired, final. One by id, refused when the rule does not take it; or every held one, of one " +
|
|
"repository when named, answering how many it retired and naming those it left held. dry \"true\" " +
|
|
"answers what it would do and changes nothing.",
|
|
Input: schema(map[string]string{"why": "why, kept with every transition",
|
|
"id": "one delivery's id; every held one when empty",
|
|
"repository": "owner/repository: only its held deliveries",
|
|
"dry": "\"true\": what it would retire, changing nothing"}, []string{"why"}, "dry"),
|
|
// Added after the seat's holder shipped (novox/hq issue 313): optional until mesh-delivery serves it.
|
|
Optional: true},
|
|
}
|
|
}
|
|
|
|
// SeatSays is whether a consumed `<seat>.<event>` names one of the seat's own events: the seat emits it,
|
|
// exactly or by one of its patterns (`log.*`). A consumed name whose emitter is a seat and whose event the
|
|
// seat does not emit is the event of the module of that name (novox/hq ADR 0239): mesh-delivery is a seat
|
|
// and the module holding it, and what the module says it says as itself, through the runtime that launches
|
|
// it — read as the seat's, a consumer would subscribe a subject nothing may publish.
|
|
func SeatSays(emits []string, event string) bool {
|
|
for _, e := range emits {
|
|
if e == event || topicMatches(e, event) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// topicMatches is whether an event's name matches a declared pattern, `*` one dot-separated segment and
|
|
// `>` or `**` the rest.
|
|
func topicMatches(pattern, event string) bool {
|
|
p, e := splitDots(pattern), splitDots(event)
|
|
for i, part := range p {
|
|
if part == ">" || part == "**" {
|
|
return len(e) > i
|
|
}
|
|
if i >= len(e) || (part != "*" && part != e[i]) {
|
|
return false
|
|
}
|
|
}
|
|
return len(p) == len(e)
|
|
}
|
|
|
|
func splitDots(s string) []string {
|
|
var out []string
|
|
start := 0
|
|
for i := 0; i < len(s); i++ {
|
|
if s[i] == '.' {
|
|
out = append(out, s[start:i])
|
|
start = i + 1
|
|
}
|
|
}
|
|
return append(out, s[start:])
|
|
}
|