Build for the merge from a copy its tests never touch, and keep or take only the same head's build
mesh/merge-gate head 060f2a9ca5fd merged into trunk 04730b54a8f2 — pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; every …
mesh/repo-check head 060f2a9ca5fd merged into trunk 04730b54a8f2 — pass: its merge-check.sh passed
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate head 060f2a9ca5fd merged into trunk 04730b54a8f2 — pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; every …
mesh/repo-check head 060f2a9ca5fd merged into trunk 04730b54a8f2 — pass: its merge-check.sh passed
mesh/delivery superseded: a newer head of the same pull request
The gate and the repository's check mount the workspace read-write, so a build from that tree could hold what the tests wrote under a key that describes the merge. A check now clones the merge outside the workspace before anything of the change runs, and builds from that. A check keeps, and a walk takes, only a build an earlier check of the same pull request at the same head made: another pull request's build, or an earlier head's, is never registered. The walk reads the verdicts once (novox/hq issue 703, review of #328).
This commit is contained in:
@@ -354,6 +354,22 @@ func Check(ctx context.Context, run Runner, spec CheckSpec, workspace, registry
|
||||
v.Head, v.Trunk, v.Merge, v.Beside, v.Members = judged.Head, judged.Trunk, judged.Merge, judged.Beside, judged.Members
|
||||
return v
|
||||
}
|
||||
// **What the merge would move is built from a checkout nothing of the check touches** (novox/hq issue 703): the
|
||||
// gate and the repository's own check run in containers that mount the workspace read-write, so they can change
|
||||
// its tree, its objects and its caches. The builds are made from a copy of the merge's objects, cloned before
|
||||
// anything of the change runs, outside the workspace — so what is kept under a key is what the key describes.
|
||||
building, buildingTree := "", ""
|
||||
if len(spec.Builds) > 0 && spec.BuildWith != nil && len(spec.Group) == 0 {
|
||||
at := judged.Merge
|
||||
if at == "" {
|
||||
at = spec.Ref
|
||||
}
|
||||
building, buildingTree, err = checkoutForTheBuilds(ctx, run, tree, at, workspace)
|
||||
if err != nil {
|
||||
return CheckVerdict{}, err
|
||||
}
|
||||
defer os.RemoveAll(building)
|
||||
}
|
||||
// **The base branch's check judges the change** (novox/hq issue 310), never the one the change brings.
|
||||
judging, err := TheCheckThatJudges(ctx, tree, spec.Base)
|
||||
if err != nil {
|
||||
@@ -610,7 +626,7 @@ func Check(ctx context.Context, run Runner, spec CheckSpec, workspace, registry
|
||||
say("check", "%s", why)
|
||||
} else {
|
||||
began := time.Now()
|
||||
v.Built = buildForTheMerge(ctx, run, spec, *spec.BuildWith, workspace, tree, judged.Merge, judged, forge,
|
||||
v.Built = buildForTheMerge(ctx, run, spec, *spec.BuildWith, building, buildingTree, judged.Merge, judged, forge,
|
||||
func(step, message string) {
|
||||
if log != nil {
|
||||
log(step, redact.redact(message))
|
||||
@@ -623,6 +639,39 @@ func Check(ctx context.Context, run Runner, spec CheckSpec, workspace, registry
|
||||
return named(v), nil
|
||||
}
|
||||
|
||||
// checkoutForTheBuilds is a clone of the commit a check builds for its merge, made before anything of the check runs,
|
||||
// outside the workspace its containers mount (novox/hq issue 703): the directory to remove, and the clone in it.
|
||||
// Cloned over git's own transport, never by linking the objects: what the check's containers later write into the
|
||||
// workspace's objects cannot reach it.
|
||||
func checkoutForTheBuilds(ctx context.Context, run Runner, tree, at, workspace string) (string, string, error) {
|
||||
dir, err := os.MkdirTemp("", "mesh-check-builds-")
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
if withinDir(workspace, dir) {
|
||||
os.RemoveAll(dir)
|
||||
return "", "", fmt.Errorf("the temporary directory %s is inside the workspace %s, which a check's containers "+
|
||||
"mount: the merge is not built from where its tests could change it", dir, workspace)
|
||||
}
|
||||
commit, err := run(ctx, tree, "git", "rev-parse", "--verify", at+"^{commit}")
|
||||
if err != nil {
|
||||
os.RemoveAll(dir)
|
||||
return "", "", fmt.Errorf("the commit to build for the merge, %s: %w", at, err)
|
||||
}
|
||||
commit = strings.TrimSpace(commit)
|
||||
if _, err := run(ctx, tree, "git", "update-ref", "refs/heads/mesh-check-builds", commit); err != nil {
|
||||
os.RemoveAll(dir)
|
||||
return "", "", err
|
||||
}
|
||||
cloned := filepath.Join(dir, "merged")
|
||||
if _, err := run(ctx, dir, "git", "clone", "--quiet", "--no-local", "--no-checkout", "--branch",
|
||||
"mesh-check-builds", tree, cloned); err != nil {
|
||||
os.RemoveAll(dir)
|
||||
return "", "", fmt.Errorf("cannot copy the merge to build it: %w", err)
|
||||
}
|
||||
return dir, cloned, nil
|
||||
}
|
||||
|
||||
// builtCount is how many of a check's builds for its merge were built.
|
||||
func builtCount(built []CheckBuilt) int {
|
||||
n := 0
|
||||
|
||||
Reference in New Issue
Block a user