From fa6dc3a48b0c687cdcbd39255d50673bf1c6d950 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 2 Nov 2026 12:52:10 +0100 Subject: [PATCH] Retake a pin whose forge listing failed, naming the forge's cause When the forge's listing of pull request heads fails, the fetch now says it as a download failure that may be retaken, so a forge outage is asked again and not held as a refusal (issue 1748, issue 1126 review 3). Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL --- modules/mesh-build-go/cmd/mesh-build-go/pins.go | 3 ++- modules/mesh-build-go/cmd/mesh-build-go/versions_test.go | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/modules/mesh-build-go/cmd/mesh-build-go/pins.go b/modules/mesh-build-go/cmd/mesh-build-go/pins.go index a4452e41..69061e2a 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/pins.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/pins.go @@ -139,7 +139,8 @@ func (m *Module) placePin(ctx context.Context, root string, p pin, failure strin repository := "novox/" + p.repo r := m.Run(ctx, []string{"GIT_TERMINAL_PROMPT=0"}, "git", "-c", "credential.helper=", "ls-remote", m.remote(repository), "refs/pull/*/head") if r.Status != 0 || r.Err != "" { - return "", fmt.Errorf("the pin of %s at commit %s: listing the pull requests of %s: %s", p.module, p.short, repository, forgekey.Said(r.Err+"\n"+r.Stderr)) + // The forge did not answer: retaken, with its own cause, never held as a refusal until the module changes (issue 1748). + return "", fmt.Errorf("the pin of %s at commit %s: listing the pull requests of %s failed (a download failure that may be retaken): %s", p.module, p.short, repository, forgekey.Said(r.Err+"\n"+r.Stderr)) } commit, ref := "", "" for _, l := range strings.Split(r.Stdout, "\n") { diff --git a/modules/mesh-build-go/cmd/mesh-build-go/versions_test.go b/modules/mesh-build-go/cmd/mesh-build-go/versions_test.go index b5288c37..3d28eafd 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/versions_test.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/versions_test.go @@ -26,6 +26,7 @@ func TestAnAskedVersionIsWrittenIntoTheModfileWhateverGoModNames(t *testing.T) { failing bool built, said, edit string failsWith string // a download failure that is not an unknown revision: the step fails with go's own words + forgeDown bool // the forge's listing of pull request heads fails too }{ {name: "a trunk commit newer than go.mod's", asked: trunk, answer: `{"Path":"` + sdk + `","Version":"v0.1.15-0.20261101000000-aaaaaaaaaaaa","Sum":"h1:zip=","GoModSum":"h1:mod="}`, @@ -45,6 +46,10 @@ func TestAnAskedVersionIsWrittenIntoTheModfileWhateverGoModNames(t *testing.T) { built: commitSHA, said: "placed from the pull request's head"}, {name: "a lookup that times out is no pin", asked: offHead, failing: true, failsWith: "i/o timeout", answer: `{"Path":"` + sdk + `","Error":"git.novox.be/novox/mesh-sdk/go@` + offHead + `: dial tcp: lookup git.novox.be on 10.10.0.3:53: read udp 10.10.0.3:42292->10.10.0.3:53: i/o timeout"}`}, + // The forge's own listing failing is a failure that may be retaken too, with its own cause (review 3). + {name: "a forge that cannot be listed is retaken", asked: commitSHA, failing: true, forgeDown: true, + failsWith: "unable to access the forge", + answer: `{"Path":"` + sdk + `","Error":"invalid version: unknown revision ` + pinShort + `"}`}, {name: "a refused connection is no pin", asked: offHead, failing: true, failsWith: "connection refused", answer: `{"Path":"` + sdk + `","Error":"git ls-remote -q origin in /tmp/gopath: dial tcp 10.10.0.1:443: connect: connection refused"}`}, } { @@ -66,6 +71,9 @@ func TestAnAskedVersionIsWrittenIntoTheModfileWhateverGoModNames(t *testing.T) { if name == "go" && strings.Contains(line, "/other mod ") { return forgekey.Ran{} // other/ requires nothing Go cannot fetch } + if name == "git" && strings.Contains(line, "ls-remote") && c.forgeDown { + return forgekey.Ran{Status: 128, Stderr: "fatal: unable to access the forge: Could not resolve host\n"} + } if name == "go" && strings.Contains(line, " mod download -json "+sdk+"@") { h.mu.Lock() h.cmds = append(h.cmds, cmdRecord{env: env, line: line})