From fff3b819d383492fd474bf7ff05e3b00a085fd0c Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 12 Nov 2026 15:23:48 +0100 Subject: [PATCH] A check step that errors after its fetch merged still answers its fetch A level that does not compile or generate ended the check step failed with no result, so the checker could not tell a merged fetch from one that never answered, and previewed and judged no manifest or composition of the member. The step now ends failed with its answer all the same: its fetch and the levels so far beside the error, which the step's end already keeps. Builds: design 47 G A-286 (G-22-lead-answers-2.md at hq 41dd30fe; issue 1921; principle 3) Quick: this checker on main; thorough: the same rule in G's checker (join 11, J15). Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h --- modules/mesh-build-go/buildstep/askrun.go | 5 +++- .../mesh-build-go/buildstep/askrun_test.go | 27 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/modules/mesh-build-go/buildstep/askrun.go b/modules/mesh-build-go/buildstep/askrun.go index 6400ec15d..027b3e1ba 100644 --- a/modules/mesh-build-go/buildstep/askrun.go +++ b/modules/mesh-build-go/buildstep/askrun.go @@ -303,7 +303,10 @@ func (s AskSteps) check(ctx context.Context, job sdkstep.CheckJob) (any, error) _, err := s.level(ctx, job, level, f, runner, &la) answer.Levels = append(answer.Levels, la) if err != nil { - return nil, err + // A level that errors after the fetch merged (it does not compile or generate) ends the step failed with its + // answer all the same: its fetch and the levels so far beside the error, which the step's end keeps, so the + // checker previews the merge from it (design 47 G, A-286). + return answer, err } } return answer, nil diff --git a/modules/mesh-build-go/buildstep/askrun_test.go b/modules/mesh-build-go/buildstep/askrun_test.go index d9a93e195..869bc859d 100644 --- a/modules/mesh-build-go/buildstep/askrun_test.go +++ b/modules/mesh-build-go/buildstep/askrun_test.go @@ -285,6 +285,33 @@ func TestRunAskChecksNodeModulesAndConflicts(t *testing.T) { if err != nil || len(r.calls) != 1 || len(out.(sdkstep.CheckAnswer).Levels) != 0 { t.Fatalf("a conflict: %v %v", err, r.calls) } + // A-286: a level that errors after the fetch merged ends the step failed with its answer all the same, its fetch and + // the levels so far beside the error, and the step's end keeps it, so the checker previews the merge from it. + r = &recorder{fetch: map[string]any{"workspace": "/w", "merge": "m1", "modules": []string{"a"}}, tests: map[string]bool{"a": true}} + s = r.steps() + s.Digest = nil + passing := s.Test + s.Test = func(ctx context.Context, args map[string]any) (any, error) { + if args["level"] == sdkstep.LevelIntegration { + return nil, errors.New("does not compile") + } + return passing(ctx, args) + } + errs := ask(sdkstep.CheckJob{Levels: []string{sdkstep.LevelUnit, sdkstep.LevelIntegration}, Fetch: sdkstep.Fetch{Repository: "novox/x", Commit: runCommit}}) + out, err = RunAsk(context.Background(), s, errs) + if a, _ := out.(sdkstep.CheckAnswer); err == nil || a.Fetch.Merge != "m1" || len(a.Levels) != 2 || len(a.Levels[0].Tests) != 1 { + t.Fatalf("an erring level: %v, answer %+v: want the error beside the fetch and both levels", err, out) + } + k := newKeys() + id, err := Start(context.Background(), k.put, "ace", "test", func(ctx context.Context) (any, error) { return RunAsk(ctx, s, errs) }) + if err != nil { + t.Fatal(err) + } + k.waitEnd(t) + var kept sdkstep.CheckAnswer + if end := k.last("ace." + id); end.State != sdkstep.StepFailed || json.Unmarshal(end.Result, &kept) != nil || kept.Fetch.Merge != "m1" { + t.Fatalf("the failed end %+v keeps no answer with its fetch", end) + } } // Issue 1289: the packages whose tests changed run first. Since 2026-11-02 (the operator: "A failed check shows only its