checker_verdicts and checker_pull say which checking program judged a verdict, its build and the heads it read (issue 1921)
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
@@ -233,7 +233,7 @@ func SeatTryTools(tr Trying) []stdio.Tool {
|
||||
func Tools(r check.Reader) []stdio.Tool {
|
||||
return []stdio.Tool{
|
||||
{Name: check.VerdictsReadTool,
|
||||
Description: "The verdicts the checker holds, each as stored under verdicts.<group>.<heads>: its state, every failure it names one line each (every member's failed tests, refused steps and conflicts, the manifests' refusals and the composition), the tests run, kept and skipped per level, the time of each part, the trunk heads it judged against and the composition, with the full " +
|
||||
Description: "The verdicts the checker holds, each as stored under verdicts.<group>.<heads>: its state, every failure it names one line each (every member's failed tests, refused steps and conflicts, the manifests' refusals and the composition), the tests run, kept and skipped per level, the time of each part, the trunk heads it judged against, the composition and which checking program judged it (judged: its build and the heads it read), with the full " +
|
||||
"report of the status each pull request carries (the line the forge shows is cut at 140 characters, this is not). With a group, that group's only. Read-only.",
|
||||
Input: map[string]any{"type": "object", "properties": map[string]any{
|
||||
"group": map[string]any{"type": "string", "description": "the delivery group's branch name"}}},
|
||||
@@ -243,7 +243,7 @@ func Tools(r check.Reader) []stdio.Tool {
|
||||
return cutAnswer(map[string]any{"verdicts": vs}, cut), err
|
||||
}},
|
||||
{Name: check.PullReadTool,
|
||||
Description: "The verdict that judges one pull request, every failure it names one line each (all of them, not only the first the status line shows), and the full report of its status mesh/check. Read-only.",
|
||||
Description: "The verdict that judges one pull request, every failure it names one line each (all of them, not only the first the status line shows), which checking program judged it (judged: its build, its key and the heads it read), and the full report of its status mesh/check. Read-only.",
|
||||
Input: map[string]any{"type": "object", "required": []string{"repository", "number"}, "properties": map[string]any{
|
||||
"repository": map[string]any{"type": "string", "description": "<owner>/<name>"},
|
||||
"number": map[string]any{"type": "integer", "description": "the pull request's number"}}},
|
||||
|
||||
@@ -65,7 +65,10 @@ type VerdictRead struct {
|
||||
Verdict json.RawMessage `json:"verdict"`
|
||||
// Failed is everything the verdict names as failed, one line each, in the order judged (failedLines): every member's
|
||||
// failed tests, refused steps and conflicts, the manifests' refusals and the composition (the operator, 2026-11-02).
|
||||
Failed []string `json:"failed,omitempty"`
|
||||
Failed []string `json:"failed,omitempty"`
|
||||
// Judged says which checking program judged the verdict, in one line (judgedLine): where it was built, the key its build
|
||||
// is kept under, whether this check built it, and the heads it read (issue 1921); empty for a verdict written before.
|
||||
Judged string `json:"judged,omitempty"`
|
||||
Reports map[string]string `json:"reports,omitempty"`
|
||||
Note string `json:"note,omitempty"`
|
||||
}
|
||||
@@ -90,6 +93,7 @@ func (r Reader) read(key string, raw json.RawMessage) (VerdictRead, error) {
|
||||
return out, fmt.Errorf("%s holds what is not a verdict: %w", key, err)
|
||||
}
|
||||
out.Failed = failedLines(v)
|
||||
out.Judged = judgedLine(v.JudgedBy)
|
||||
c, ok := r.candidate(v.Group)
|
||||
if !ok || (c.HeadsHash != v.Heads && GateHeads(c) != v.Heads) {
|
||||
out.Note = "the candidate no longer holds these heads"
|
||||
@@ -752,3 +756,20 @@ func (r Reader) buildsNotEnded(c delivery.Candidate) string {
|
||||
sort.Strings(out)
|
||||
return strings.Join(slices.Compact(out), ", ")
|
||||
}
|
||||
|
||||
// judgedLine is a verdict's JudgedBy in one line, as the verdict tools answer it.
|
||||
func judgedLine(by *delivery.JudgedBy) string {
|
||||
if by == nil {
|
||||
return ""
|
||||
}
|
||||
built := "kept"
|
||||
if by.Built {
|
||||
built = "built for this check"
|
||||
}
|
||||
heads := make([]string, len(by.Heads))
|
||||
for i, h := range by.Heads {
|
||||
heads[i] = h.Repository + " " + h.Commit
|
||||
}
|
||||
return fmt.Sprintf("by the checking program %s of %s at %s (%s), %s as %s, over %s", by.Program.Package, by.Program.Repository,
|
||||
by.Program.Commit, by.Program.Dir, built, by.Key, strings.Join(heads, ", "))
|
||||
}
|
||||
|
||||
@@ -64,15 +64,23 @@ func TestTheVerdictToolsAnswerTheStoredVerdictWithTheFullReportOfEachPullRequest
|
||||
if got := vs[0].Reports["novox/mesh-delivery#7"]; !strings.HasPrefix(got, "pass 111111111111 on aaaaaaaaaaaa") || !strings.Contains(got, "composition not yet run") {
|
||||
t.Errorf("reports = %v", vs[0].Reports)
|
||||
}
|
||||
if vs[0].Judged != "" {
|
||||
t.Errorf("judged = %q of a verdict with no JudgedBy", vs[0].Judged)
|
||||
}
|
||||
if only, _, _ := rd.Verdicts("feat/other"); len(only) != 0 {
|
||||
t.Errorf("another group's verdicts = %+v", only)
|
||||
}
|
||||
// A failed verdict is answered with every failure it names, one line each (the operator, 2026-11-02).
|
||||
raw, _ := delivery.EncodeVerdict(delivery.Verdict{Group: "feat/x", Heads: "0123456789ab", State: delivery.VerdictFail,
|
||||
Failed: delivery.FailedFirst{Test: "unit: m/a.TestA", Words: "a_test.go:3: boom\nmore"},
|
||||
Failures: []delivery.FailedFirst{{Test: "unit: m/a.TestA", Words: "a_test.go:3: boom"}, {Machine: "g14", Words: "route-proxy is defined twice"}}})
|
||||
if got, _ := rd.read(key, raw); strings.Join(got.Failed, " | ") != "unit: m/a.TestA: a_test.go:3: boom | g14: route-proxy is defined twice" {
|
||||
t.Errorf("failed = %q", got.Failed)
|
||||
Failures: []delivery.FailedFirst{{Test: "unit: m/a.TestA", Words: "a_test.go:3: boom"}, {Machine: "g14", Words: "route-proxy is defined twice"}},
|
||||
// Issue 1921: it names the checking program that judged it, its build and the heads it read.
|
||||
JudgedBy: &delivery.JudgedBy{Program: delivery.RunProgram{Repository: repoA, Commit: head1, Dir: CheckingProgramDir, Package: CheckingProgramPackage},
|
||||
Key: "program-0123456789abcdef", Built: true, Heads: []delivery.RunHead{{Repository: repoA, Commit: head1}}}})
|
||||
want := "by the checking program " + CheckingProgramPackage + " of " + repoA + " at " + head1 + " (" + CheckingProgramDir +
|
||||
"), built for this check as program-0123456789abcdef, over " + repoA + " " + head1
|
||||
if got, _ := rd.read(key, raw); strings.Join(got.Failed, " | ") != "unit: m/a.TestA: a_test.go:3: boom | g14: route-proxy is defined twice" || got.Judged != want {
|
||||
t.Errorf("failed = %q, judged %q, want %q", got.Failed, got.Judged, want)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user