build(node): add reproducible build target for morphnode - #1067
FletcherMan wants to merge 6 commits into
Conversation
`make morphnode` embeds the wall-clock build time, so the same source tree
produces a different binary on every build. Add `make morphnode-repro`, which
builds the same binary but byte-identically:
- BuildTime becomes the constant "reproducible"; a reproducible artifact has
no meaningful build time, and reusing the commit time here would misreport
what BuildTime means
- -buildid= drops the Go build ID, which varies with the build cache state
- -trimpath drops absolute checkout paths
- -no_uuid drops the random LC_UUID that Apple's linker stamps into every
Mach-O binary (Linux's GNU build-id is already content-derived)
Without -no_uuid the binaries still differed, in 47 bytes: the UUID itself plus
the ad-hoc code signature covering it.
`make morphnode` is deliberately left untouched, so its BuildTime keeps
reporting when the binary was actually built.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Warning Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
`go build` embeds vcs.revision, vcs.time and vcs.modified. They are stable for a fixed commit, but vcs.modified flips with a dirty tree and the whole block is silently omitted when .git is absent — so the same source can still produce different binaries depending on how the build environment is set up. Docker builds that exclude .git hit exactly this. Version and GitCommit already carry the same information, so drop the stamps. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Claude Code Review
Claude Code Review is paused for this repository. To reconnect it, an admin of this repository's GitHub organization (or the account owner, for personal repositories) who can also manage your Claude organization's Code Review settings needs to re-link GitHub in Code Review settings. This is a one-time step.
Tip: disable this comment in your organization's Code Review settings.
make morphnodeembeds the wall-clock build time, so the same source tree produces a different binary every time.Adds
make morphnode-repro: same binary, byte-identical across builds. It is just$(MAKE) morphnode REPRO=1, so there is only one build recipe.make morphnodeis unchanged and still reports the real build time.REPRO=1removes five sources of variance:BuildTimeset to the constantreproducible-buildid=-trimpathvcs.modifiedflips on a dirty tree, and the block is omitted entirely when.gitis absent)-buildvcs=falseLC_UUIDon macOS-extldflags=-Wl,-no_uuid, darwin onlyCommit time is deliberately not used for
BuildTime— a reproducible artifact has no build time, and reusing the commit time would misreport what the field means. UseGit Commit/Versionto identify the source.MakefileEc2.mkswitches the mainnet node target over tomorphnode-reproand prints the sha256 of the artifact before upload.Verified on macOS/arm64, go1.24.0, including after
go clean -cache: two runs ofmorphnode-reprogive an identical sha256, two runs ofmorphnodedo not.Note: cross-machine reproducibility also needs a fixed toolchain, since
morphnodeis built with cgo.