Skip to content

fix(gnark-ffi): align Go toolchain with go.mod and skip VCS stamping#2771

Open
wstran wants to merge 2 commits into
succinctlabs:mainfrom
wstran:fix/gnark-ffi-go-toolchain
Open

fix(gnark-ffi): align Go toolchain with go.mod and skip VCS stamping#2771
wstran wants to merge 2 commits into
succinctlabs:mainfrom
wstran:fix/gnark-ffi-go-toolchain

Conversation

@wstran
Copy link
Copy Markdown

@wstran wstran commented May 4, 2026

Motivation

Two related production-friction issues in the gnark-ffi Go build:

1. CI Go version drifted from go.mod

The gnark-ffi Go module declares go 1.24.0 (since #998 / Dec 2025) but CI configuration still pins:

  • .github/actions/setup/action.yml: go-version: \"1.22\"
  • .github/workflows/release.yml (×2): go-version: \"^1.22.1\"

When Go 1.22 builds against a go 1.24.0 go.mod, GOTOOLCHAIN=auto (default since Go 1.21) silently downloads the 1.24 toolchain on every run. Locally reproducible:

$ go version
go version go1.22.10 linux/arm64
$ time go build -tags=debug -buildmode=c-archive .
go: downloading go1.24.0 (linux/arm64)
...
real    0m9.5s

Costs:

  • ~10 s per build pulled from go.dev (network dependency)
  • Silent failure mode when go.dev is unreachable
  • On older bases (Debian Bookworm apt golang = Go 1.19), parsing fails before toolchain switch can run: invalid go version '1.24.0': must match format 1.23

2. go build aborts with cryptic VCS error in restricted environments

Since Go 1.18, go build defaults to embedding VCS metadata, which requires git to be runnable in the module directory. In Docker bind-mount setups (UID mismatch between host and container) or sandboxed CI environments, this fails:

error obtaining VCS status: exit status 128
        Use -buildvcs=false to disable VCS stamping.

thread 'main' panicked at crates/recursion/gnark-ffi/build.rs:72:17:
Go build failed

The build output is a static C archive linked into the Rust binary; embedded Go VCS metadata is never consumed. The Rust binary already carries its own VCS info via vergen-style stamping at the Rust layer.

Changes

  1. CI (action.yml + release.yml ×2): replace go-version with go-version-file: \"crates/recursion/gnark-ffi/go/go.mod\". setup-go reads the go directive directly, eliminating drift and the auto-toolchain download. Future go.mod bumps propagate to CI without separate edits.

  2. crates/recursion/gnark-ffi/build.rs: pass -buildvcs=false to go build. Removes the git-runnability requirement and the cryptic failure mode without changing the produced artifact.

Verification

Reproduced locally on rust:1.91-slim-bookworm (Debian, Go 1.19 from apt) and with Go 1.22 / 1.24 from the official tarball:

Setup Before After
Go 1.19 parse error on go.mod n/a (CI installs 1.24 directly via go-version-file)
Go 1.22 + Docker bind-mount downloads Go 1.24 (~10 s), then VCS error 128 builds clean (Go 1.24 installed up-front, no VCS lookup)
Go 1.24 + clean checkout builds, embeds VCS info into unused archive builds, skips VCS stamping

cargo +nightly fmt --check --all passes. cargo check -p sp1-recursion-gnark-ffi --features native passes after the build.rs change.

Notes

  • No behavior change for the released binaries: VCS info in the static .a is only ever read via go version -m, which is not part of any SP1 release path.
  • go-version-file is supported by actions/setup-go v3+ (current pin is v5).
  • Caching is preserved via the existing cache-dependency-path: \"**/go.sum\".

@wstran wstran changed the base branch from dev to main May 11, 2026 10:37
@wstran wstran force-pushed the fix/gnark-ffi-go-toolchain branch from 5e78674 to f36cca5 Compare May 11, 2026 10:44
@wstran
Copy link
Copy Markdown
Author

wstran commented May 11, 2026

Retargeted from dev to main and rebased the branch onto the current main HEAD — dev and main have separated histories and dev has been frozen for ~9 days. The three changes (setup action go-version-file, two release.yml setup-go calls, and -buildvcs=false in gnark-ffi/build.rs) apply cleanly to current main.

wstran added 2 commits May 17, 2026 02:26
The gnark-ffi Go module declares `go 1.24.0` but CI workflows pin
`go-version: "1.22"` and `^1.22.1`. Go 1.22 then auto-downloads the
1.24 toolchain on every build via GOTOOLCHAIN, adding a network
dependency on go.dev and ~10 seconds to each run.

Switch setup-go to `go-version-file: crates/recursion/gnark-ffi/go/go.mod`
so the action installs the exact version required by go.mod. Future
go.mod bumps propagate to CI without separate edits.
`go build` defaults to embedding VCS metadata (Go 1.18+), which requires
git to be runnable in the module directory. This fails with cryptic
`error obtaining VCS status: exit status 128` whenever git cannot run,
e.g. Docker bind-mount UID mismatches or sandboxed CI runners with
restricted git config.

The build output is a static C archive linked into the Rust binary;
embedded Go VCS metadata is unused. Pass `-buildvcs=false` to skip it.
@wstran wstran force-pushed the fix/gnark-ffi-go-toolchain branch from f36cca5 to 9cde723 Compare May 16, 2026 19:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant