Say in mesh-build-go's README that it builds with the installed go and its digest holds no Go version (issue 1572, ADR 0477)
mesh/merge-gate head d699708fb382 merged into trunk 17d2f7fd5df1 — pass: builds mesh-build-go, mesh-build-node → g14, novox, shanks; no bus step; every mac…
mesh/repo-check head d699708fb382 merged into trunk 17d2f7fd5df1 — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-…
mesh/delivery delivered

This commit is contained in:
2026-10-21 08:07:15 +00:00
parent e8046fca87
commit d699708fb3
+17 -15
View File
@@ -8,19 +8,20 @@ builder uses it.
## The recipe
`cmd/mesh-build-go/recipe.go` names the one Go version the module builds with (`RecipeGo`), the postgres major
version the integration level tests with, and the recipe's own version. The recipe version is a hash of those and of
the nats-server library's version, read from the program's build information, so a change of any of them moves it.
The module builds with the `go` its node has installed (`GOTOOLCHAIN=local`; ADR 0477 §1, issue 1572) and names no Go
version. The versions of the build nodes are agreed by the indexer, which builds a language's modules only while the
nodes that report agree (ADR 0465), and kept equal by the weekly upgrade of every node's packages (ADR 0477 §5).
`cmd/mesh-build-go/recipe.go` holds the steps' own version (`RecipeSteps`), the postgres major version the integration
level tests with, and the recipe version: a hash of those and of the nats-server library's version, read from the
program's build information, never of a Go version (ADR 0477 §3).
## The guard and the health
At start, every ten minutes, before every step and at every health look, the module reads the version of Go's own
release of the recipe's version (`go version` run with `GOTOOLCHAIN=<RecipeGo>`, ADR 0476) and writes it with the recipe version to `<node>.go` of its `toolchains` state. The probe runs with network and
the module's Go module cache (`GOMODCACHE`): while the release is missing from it, the installed Go downloads it there,
verified against Go's checksum database; no step fetches it. A machine where the release cannot be had, or that does not
report the recipe's version, refuses every step, the step ending `refused` on its key in `steps` with both versions named,
and `build_go_health` (the module's `runtime-health`) answers unhealthy with the same text, so the controller raises
the machine's condition. Moving to a new Go is a change of `RecipeGo`.
At start, every ten minutes, before every step and at every health look, the module reads the installed Go (`go version`
with `GOTOOLCHAIN=local`; nothing is downloaded) and writes it with the recipe version to `<node>.go` of its
`toolchains` state. Whatever the version, the module is healthy and `build_go_health` (the module's `runtime-health`)
names it. Only a `go` that cannot be run refuses every step, the step ending `refused` on its key in `steps` with the
cause named, and the health is then unhealthy with the same text, so the controller raises the machine's condition.
## Tools
@@ -33,7 +34,7 @@ step answers at once with its id and ends on `<node>.<id>` of `steps` (ADR 0469
`build_go_fetch {repository, commit, ref?}` fetches the commit over SSH as the module's account (`mesh-forge` is the
forge-account provision's ssh name, so the account's own ssh files and git rewrite are used) into a workspace of the
work directory, then runs `go mod download` and `go mod verify` in every directory with a `go.mod` that does not vendor,
with `GOTOOLCHAIN=<RecipeGo>`, `GOFLAGS=-mod=mod` and the module's cache directory. Every command runs with an
with `GOTOOLCHAIN=local`, `GOFLAGS=-mod=mod` and the module's cache directory. Every command runs with an
environment built from scratch (`StepRunner`): `PATH`, `HOME` and what the step passes. Workspaces older than a day
are removed.
@@ -77,8 +78,9 @@ is said until a source exists.
`build_go_digest {workspace, level}` answers in its call, for each package of the workspace that has tests at the level,
one digest of everything those tests read (ADR 0445 §5): the files, by content and under their path in the tree, of the
package and every package its test binary reaches (`go list -test -deps`) that lies in the module's own tree; the version
and checksum of every module outside it; the package's own `testdata/` files; and the Go version, the level, the build tags
and, at the integration level, the postgres major and the nats-server version. Packages of the standard library are the Go
and checksum of every module outside it; the package's own `testdata/` files; and the level, the build tags and, at the
integration level, the postgres major and the nats-server version. The Go version is not in it: the toolchain enters a
fingerprint once, as the version the build nodes agree on (ADR 0477 §3), and the standard library's packages are that
version's. A package with no tests at the level has no digest and is named in `without_tests`. A directory that vendors
is listed and tested from its vendor directory (`-mod=vendor`).
@@ -88,8 +90,8 @@ is listed and tested from its vendor directory (`-mod=vendor`).
agent's recipe (mesh-controller's `toolchain.go`, the Go entry, copied in `testdata/captured/toolchain-go-entry.txt`, and
`builder.go`): `CGO_ENABLED=0`, `GOFLAGS=-trimpath -buildvcs=false` (with `-mod=mod`, or `-mod=vendor` for a directory
that vendors), `go build -ldflags "-s -w -X main.builtFor=<system>" -o .mesh-build/<artifact>/<binary> ./<from>` in the
module's directory, by the recipe's Go release (`GOTOOLCHAIN=<RecipeGo>`, found in the module cache) from the module cache the fetch filled and no network
module's directory, by the installed go (`GOTOOLCHAIN=local`) from the module cache the fetch filled and no network
(`GOPROXY=off`). The binary is named as the build agent names it. The output directory is packed with mesh-sdk's `Pack`,
so the digest is the build agent's for the same tree. The step ends with the artifact, the binary, the digest, the size and
as the build agent packs; two build nodes on the same toolchain give the same digest for the same tree (ADR 0477 §6). The step ends with the artifact, the binary, the digest, the size and
the path of the archive, which stays in the workspace's `artifacts` directory: publishing it is the builder's, in a later
release. An artifact that is not a Go bundle fails the step naming it.