Build a change once: the check builds what its merge moves, the walk takes it by key
mesh/merge-gate out of date: judged against trunk bff5b7f0e4f8, the trunk is now 372faebf2824; judged again on a recheck or when it is merged
mesh/repo-check out of date: judged against trunk bff5b7f0e4f8, the trunk is now 372faebf2824; judged again on a recheck or when it is merged
mesh/delivery-group group feat/350-one-build-per-change checking: composed check out of date: novox/mesh-controller@cd49b50c4075 was judged against trunk bff5b…
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate out of date: judged against trunk bff5b7f0e4f8, the trunk is now 372faebf2824; judged again on a recheck or when it is merged
mesh/repo-check out of date: judged against trunk bff5b7f0e4f8, the trunk is now 372faebf2824; judged again on a recheck or when it is merged
mesh/delivery-group group feat/350-one-build-per-change checking: composed check out of date: novox/mesh-controller@cd49b50c4075 was judged against trunk bff5b…
mesh/delivery superseded: a newer head of the same pull request
A merge built every moved module a second time although its check had judged the same tree (issue 649). The check now builds into the scratch namespace under a reuse key (source fingerprint plus the builder's own digest), and the walk of the trunk commit copies a build of the same key by digest instead of building, saying per module why when it cannot (novox/hq ADR 0350).
This commit is contained in:
@@ -313,6 +313,59 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
// reuseKey carries a walk's leave to take a check's build from askModule to the ask it makes (novox/hq ADR 0350 §2).
|
||||
type reuseKey struct{}
|
||||
|
||||
// withReuse is ctx carrying a walk's leave to take a check's build.
|
||||
func withReuse(ctx context.Context, r *link.ReuseAsk) context.Context {
|
||||
return context.WithValue(ctx, reuseKey{}, r)
|
||||
}
|
||||
|
||||
// reuseIn is the leave ctx carries; nil for every ask but a walk's.
|
||||
func reuseIn(ctx context.Context) *link.ReuseAsk {
|
||||
r, _ := ctx.Value(reuseKey{}).(*link.ReuseAsk)
|
||||
return r
|
||||
}
|
||||
|
||||
// reuseAsked is the leave an ask carries: a walk's, and never a dry run's — a dry run registers nothing, so it
|
||||
// takes nothing either (novox/hq ADR 0350 §2, §6).
|
||||
func reuseAsked(ctx context.Context, dryRun bool) *link.ReuseAsk {
|
||||
if dryRun {
|
||||
return nil
|
||||
}
|
||||
return reuseIn(ctx)
|
||||
}
|
||||
|
||||
// reuseAskOf is a walk's leave to take a check's build: the pull requests of the merges it answers.
|
||||
func reuseAskOf(p *inventory.Plan) *link.ReuseAsk {
|
||||
r := &link.ReuseAsk{}
|
||||
if p.Delivery == nil {
|
||||
return r
|
||||
}
|
||||
seen := map[link.PullRef]bool{}
|
||||
for _, m := range p.Delivery.Merges {
|
||||
pull, ok := pullOf(m)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if !seen[pull] {
|
||||
seen[pull] = true
|
||||
r.Pulls = append(r.Pulls, pull)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// pullOf is a merge's pull request: owner and repository, the last two parts of however the repository is spelled
|
||||
// (owner/repo, a path on the git seat, a URL), and its number. False when the merge names none.
|
||||
func pullOf(m inventory.PlanMerge) (link.PullRef, bool) {
|
||||
parts := strings.Split(strings.Trim(strings.TrimSuffix(m.Repository, ".git"), "/"), "/")
|
||||
if len(parts) < 2 || m.Number <= 0 || parts[len(parts)-2] == "" || parts[len(parts)-1] == "" {
|
||||
return link.PullRef{}, false
|
||||
}
|
||||
return link.PullRef{Owner: parts[len(parts)-2], Repo: parts[len(parts)-1], Number: m.Number}, true
|
||||
}
|
||||
|
||||
// askModule asks the build machine for one module of a plan and marks it asked, with the id it was
|
||||
// asked under (novox/hq ADR 0219) — or failed, with the plan, when it could not be asked.
|
||||
func askModule(ctx context.Context, p *inventory.Plan, name string, byName map[string]inventory.Entry) {
|
||||
@@ -340,7 +393,9 @@ func askModule(ctx context.Context, p *inventory.Plan, name string, byName map[s
|
||||
if p.Delivery != nil && p.Delivery.Alone && carried != "" {
|
||||
ref = carried
|
||||
}
|
||||
id, err := askABuild(ctx, source, e.Source.Path, ref)
|
||||
// **The walk takes the check's build of the same key** (novox/hq ADR 0350 §2): its ask says so, with the pull
|
||||
// requests it answers, whose checks name the part of a differing key.
|
||||
id, err := askABuild(withReuse(ctx, reuseAskOf(p)), source, e.Source.Path, ref)
|
||||
if err != nil {
|
||||
state.State = "failed"
|
||||
state.Why = err.Error()
|
||||
@@ -359,7 +414,7 @@ func askModule(ctx context.Context, p *inventory.Plan, name string, byName map[s
|
||||
state.State = "asked"
|
||||
state.AskedAt = &now
|
||||
state.Build = id
|
||||
state.Why, state.Commit, state.BuiltAt = "", "", nil
|
||||
state.Why, state.Commit, state.BuiltAt, state.Made = "", "", nil, ""
|
||||
}
|
||||
|
||||
// planBuilt marks a module built (or failed) in every open plan whose current tier holds it, and
|
||||
@@ -371,6 +426,12 @@ func askModule(ctx context.Context, p *inventory.Plan, name string, byName map[s
|
||||
// would send machines, and the next tier, what the later merge replaced. asked is zero when the
|
||||
// build's request time is not known, and such an outcome is taken as before.
|
||||
func planBuilt(ctx context.Context, open *stores, module, commit, failed string, asked time.Time, id string) {
|
||||
planBuiltSaying(ctx, open, module, commit, failed, asked, id, "")
|
||||
}
|
||||
|
||||
// planBuiltSaying is planBuilt keeping what the build did — "reused from <check build>" or "built: <why>" (novox/hq
|
||||
// ADR 0350 §4) — on the module of the walk it answers.
|
||||
func planBuiltSaying(ctx context.Context, open *stores, module, commit, failed string, asked time.Time, id, made string) {
|
||||
inv := open.inventory
|
||||
// One controller works the plans at a time (novox/hq issue 213); an outcome waits its turn rather
|
||||
// than write over what the holder is about to save. Not taken, it is still in the build records,
|
||||
@@ -436,6 +497,7 @@ func planBuilt(ctx context.Context, open *stores, module, commit, failed string,
|
||||
state.State = "built"
|
||||
state.BuiltAt = &now
|
||||
state.Commit = commit
|
||||
state.Made = made
|
||||
}
|
||||
if err := inv.SavePlan(ctx, p); err != nil {
|
||||
fmt.Printf("%s: cannot keep the plan: %v\n", p.ID, err)
|
||||
|
||||
Reference in New Issue
Block a user