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:
+18
-5
@@ -114,11 +114,23 @@ type ReuseAsk struct {
|
||||
|
||||
// CheckedBuild is one build a check's verdict names: the pull request it checked, its ask, and the build.
|
||||
type CheckedBuild struct {
|
||||
Pull PullRef `json:"pull"`
|
||||
Check string `json:"check"`
|
||||
Pull PullRef `json:"pull"`
|
||||
Check string `json:"check"`
|
||||
// Head is the pull request's head the check judged, as its verdict says it (twelve characters): a build is
|
||||
// taken or kept only by a check of the same head (novox/hq issue 703).
|
||||
Head string `json:"head,omitempty"`
|
||||
Built CheckBuilt `json:"built"`
|
||||
}
|
||||
|
||||
// SameHead says two spellings of a commit name the same one: both said, one the other's beginning, at least
|
||||
// twelve characters of it (a verdict says twelve).
|
||||
func SameHead(a, b string) bool {
|
||||
if len(a) > len(b) {
|
||||
a, b = b, a
|
||||
}
|
||||
return len(a) >= 12 && strings.HasPrefix(b, a)
|
||||
}
|
||||
|
||||
// PullRef names a pull request.
|
||||
type PullRef struct {
|
||||
Owner string `json:"owner"`
|
||||
@@ -164,9 +176,10 @@ type CheckRequest struct {
|
||||
// each, from the merge it judged, into the scratch namespace once it has judged and not failed, for the walk to
|
||||
// take. A build seat from before it builds nothing, and the walk builds as before.
|
||||
Builds []CheckBuild `json:"builds,omitempty"`
|
||||
// Named are the builds the seat's verdicts name for those modules, of any pull request, within the week check
|
||||
// builds are kept (novox/hq issue 703): the check keeps a build kept under a module's unchanged key, instead of
|
||||
// building it again, only when one of these names its key and every digest. A build seat from before it builds.
|
||||
// Named are the builds the seat's verdicts of earlier checks of this pull request at this head name, within the
|
||||
// week check builds are kept (novox/hq issue 703): asked again because only the trunk moved, the check keeps a
|
||||
// build kept under a module's unchanged key, instead of building it again, only when one of these names its key
|
||||
// and every digest. Never another pull request's, nor an earlier head's. A build seat from before it builds.
|
||||
Named []CheckedBuild `json:"named,omitempty"`
|
||||
// Try marks a branch tried before its pull request (novox/hq issue 686): the repository's own check for a
|
||||
// pushed branch or commit, asked by a builder through the controller's `try` verb. Its outcome is read from
|
||||
|
||||
@@ -38,9 +38,9 @@ func TestNatsTheBuildsAWalkMayTakeAreTheChecksOutcomesOfItsPullRequests(t *testi
|
||||
}
|
||||
}
|
||||
|
||||
// A check reads the builds every pull request's checks made of the modules it builds, and a kept build is named as
|
||||
// the check's that built it (novox/hq issue 703).
|
||||
func TestNatsACheckReadsTheBuildsOfItsModulesAndAKeptBuildIsTheBuildersCheck(t *testing.T) {
|
||||
// A build is read with the head its check judged, and a kept build is named as the check's that built it (novox/hq
|
||||
// issue 703).
|
||||
func TestNatsAKeptBuildIsTheBuildersCheckAndEveryBuildSaysItsHead(t *testing.T) {
|
||||
js := aBus(t)
|
||||
since := time.Now().Add(-time.Minute)
|
||||
say := func(r BuildResult) {
|
||||
@@ -49,21 +49,39 @@ func TestNatsACheckReadsTheBuildsOfItsModulesAndAKeptBuildIsTheBuildersCheck(t *
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
mine := &CheckRequest{Owner: "novox", Repo: "shop", Number: 7}
|
||||
app := CheckBuilt{Module: "app", Key: "r1:1", Made: []MadeArtifact{{Name: "server", Reference: "s/app/server@sha256:a"}}}
|
||||
web := CheckBuilt{Module: "web", Key: "r1:2", Made: []MadeArtifact{{Name: "server", Reference: "s/web/server@sha256:b"}}}
|
||||
say(BuildResult{ID: "build-1", Checked: &CheckRequest{Owner: "novox", Repo: "shop", Number: 7},
|
||||
Check: &CheckOutcome{Verdict: "pass", Built: []CheckBuilt{app, web}}})
|
||||
say(BuildResult{ID: "build-1", Checked: mine, Check: &CheckOutcome{Verdict: "pass", Head: "aaaaaaaaaaaa",
|
||||
Built: []CheckBuilt{app}}})
|
||||
kept := app
|
||||
kept.Kept = "build-1"
|
||||
say(BuildResult{ID: "build-2", Checked: &CheckRequest{Owner: "novox", Repo: "till", Number: 3},
|
||||
Check: &CheckOutcome{Verdict: "pass", Built: []CheckBuilt{kept}}})
|
||||
say(BuildResult{ID: "build-2", Checked: mine, Check: &CheckOutcome{Verdict: "pass", Head: "aaaaaaaaaaaa",
|
||||
Built: []CheckBuilt{kept}}})
|
||||
|
||||
got, err := ReadCheckBuildsOf(t.Context(), js, TheBuildMachine, []string{"app"}, since)
|
||||
got, err := ReadCheckBuilds(t.Context(), js, TheBuildMachine, []PullRef{{Owner: "novox", Repo: "shop", Number: 7}}, since)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(got) != 2 || got[0].Check != "build-1" || got[0].Pull.Repo != "till" || got[1].Check != "build-1" ||
|
||||
got[1].Built.Module != "app" {
|
||||
if len(got) != 2 || got[0].Check != "build-1" || got[0].Built.Kept != "build-1" || got[0].Head != "aaaaaaaaaaaa" ||
|
||||
got[1].Check != "build-1" || got[1].Head != "aaaaaaaaaaaa" {
|
||||
t.Fatalf("read %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
// Two spellings of a head are the same head only when both say at least twelve characters of it.
|
||||
func TestSameHeadNeedsTwelveCharactersOfBoth(t *testing.T) {
|
||||
for _, c := range []struct {
|
||||
a, b string
|
||||
same bool
|
||||
}{
|
||||
{"aaaaaaaaaaaa", "aaaaaaaaaaaabbbb", true},
|
||||
{"aaaaaaaaaaaabbbb", "aaaaaaaaaaaa", true},
|
||||
{"aaaaaaaaaaaa", "aaaaaaaaaaab", false},
|
||||
{"", "", false},
|
||||
{"aaaa", "aaaaaaaaaaaa", false},
|
||||
} {
|
||||
if SameHead(c.a, c.b) != c.same {
|
||||
t.Errorf("SameHead(%q, %q) is %v", c.a, c.b, !c.same)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,10 +172,13 @@ type Announcement struct {
|
||||
// which branch, producing which commit. The mesh matches it against every module's recorded
|
||||
// source and builds what moved, bases first.
|
||||
type SourceMoved struct {
|
||||
Owner string `json:"owner"`
|
||||
Repo string `json:"repo"`
|
||||
Base string `json:"base"`
|
||||
Head string `json:"head"`
|
||||
Owner string `json:"owner"`
|
||||
Repo string `json:"repo"`
|
||||
Base string `json:"base"`
|
||||
Head string `json:"head"`
|
||||
// HeadSHA is the head commit the forge merged (novox/hq issue 703): a walk takes only a build a check of that
|
||||
// head made. Empty from a forge module from before it, and then the walk takes no check's build.
|
||||
HeadSHA string `json:"head_sha,omitempty"`
|
||||
Commit string `json:"merge_commit_sha"`
|
||||
CloneURL string `json:"clone_url"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
|
||||
+1
-14
@@ -378,19 +378,6 @@ func ReadCheckBuilds(ctx context.Context, js *broker.JetStream, seat string, pul
|
||||
return readCheckBuilds(ctx, js, seat, since, func(p PullRef, _ CheckBuilt) bool { return wanted[p] })
|
||||
}
|
||||
|
||||
// ReadCheckBuildsOf is every build the seat's checks of any pull request said they made, or kept, of those modules
|
||||
// since a moment (novox/hq issue 703): what a check may keep instead of building. Newest first.
|
||||
func ReadCheckBuildsOf(ctx context.Context, js *broker.JetStream, seat string, modules []string, since time.Time) ([]CheckedBuild, error) {
|
||||
if len(modules) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
wanted := map[string]bool{}
|
||||
for _, m := range modules {
|
||||
wanted[m] = true
|
||||
}
|
||||
return readCheckBuilds(ctx, js, seat, since, func(_ PullRef, b CheckBuilt) bool { return wanted[b.Module] })
|
||||
}
|
||||
|
||||
// readCheckBuilds is every build the seat's checks said they made, or kept, that wanted takes. A kept build is named
|
||||
// as the check's that built it (novox/hq issue 703): the record under its key is that check's.
|
||||
func readCheckBuilds(ctx context.Context, js *broker.JetStream, seat string, since time.Time,
|
||||
@@ -428,7 +415,7 @@ func readCheckBuilds(ctx context.Context, js *broker.JetStream, seat string, sin
|
||||
if b.Kept != "" {
|
||||
check = b.Kept
|
||||
}
|
||||
out = append(out, CheckedBuild{Pull: pull, Check: check, Built: b})
|
||||
out = append(out, CheckedBuild{Pull: pull, Check: check, Head: r.Check.Head, Built: b})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user