ci: build-reproducibility — clean cdylib wasm verification for all workspaces - #1
Closed
ELKorede wants to merge 1 commit into
Closed
ci: build-reproducibility — clean cdylib wasm verification for all workspaces#1ELKorede wants to merge 1 commit into
ELKorede wants to merge 1 commit into
Conversation
Adds a CI job that starts from a clean Cargo target directory and
verifies every deployable wasm artifact is produced correctly.
Problem addressed:
- No existing CI job performed a clean build of all cdylib packages
- contracts-ci.yml only covered the bounty_escrow workspace
- wasm-size-budget.yml used a cached target (not clean) and relied on
upload-artifact for failure detection rather than explicit assertions
Changes:
- .github/workflows/build-reproducibility.yml
New workflow with 5 jobs:
• record-versions: captures rustc, cargo, and resolved soroban-sdk
versions as a build artifact
• build-contracts-bounty-escrow: cargo clean + build for the
bounty_escrow workspace (produces bounty_escrow.wasm + escrow.wasm)
• build-contracts-standalone: matrix over grainlify-core,
program-escrow, view-facade, escrow-view-facade (one clean build
each, fail-fast: false so all packages are always attempted)
• build-soroban: cargo clean + build for soroban/contracts/escrow
and soroban/contracts/program-escrow; grainlify-stream excluded
(no crate-type = cdylib, host-only testutils helper)
• summarize: collects all artifacts and prints a final report
- scripts/verify-wasm-artifacts.sh
Reusable assertion script that checks: file exists, size > 0,
WebAssembly magic bytes (\x00asm) present. Called from the workflow
and runnable locally. Exits 1 if any assertion fails.
- scripts/tests/test_verify_wasm_artifacts.sh
8 regression tests for verify-wasm-artifacts.sh using synthetic
wasm fixtures (no Rust toolchain required). All tests pass.
Authoritative cdylib target list (excludes host-only and non-cdylib):
contracts/bounty_escrow workspace → bounty_escrow.wasm, escrow.wasm
contracts/grainlify-core → grainlify_core.wasm
contracts/program-escrow → program_escrow.wasm
contracts/view-facade → view_facade.wasm
contracts/escrow-view-facade → escrow_view_facade.wasm
soroban/contracts/escrow → escrow.wasm
soroban/contracts/program-escrow → program_escrow.wasm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a dedicated CI workflow that starts from a clean Cargo target directory and verifies every deployable
cdylibwasm artifact across all workspaces. Fails the job if any expected.wasmfile is absent, empty, or lacks the WebAssembly magic bytes.Closes #[build-reproducibility issue].
Before / After
Before
contracts-ci.ymlbuilt only thebounty_escrowworkspace; the other fourcontracts/packages and the entiresoroban/workspace had no clean-build gatewasm-size-budget.ymlrestored the Cargotarget/directory from cache before building, so a silently-deleted cdylib could pass if the cached artifact was still presentupload-artifact: if-no-files-found: error— no structured check for magic bytes or file sizesoroban-sdkversion alongside each buildAfter
A new
.github/workflows/build-reproducibility.ymlruns on every push and PR that touches Rust or CI source. It:cargo cleanbefore every build — the Cargo registry cache (crate downloads) is retained but the compiledtarget/tree is always empty.scripts/verify-wasm-artifacts.sh: file exists, size > 0, WebAssembly magic bytes (\x00asm) present.Authoritative cdylib target list
contracts/bounty_escrowbounty_escrow.wasmcontracts/bounty_escrowescrow.wasmcontracts/grainlify-coregrainlify_core.wasmcontracts/program-escrowprogram_escrow.wasmcontracts/view-facadeview_facade.wasmcontracts/escrow-view-facadeescrow_view_facade.wasmsoroban/escrow.wasmsoroban/program_escrow.wasmExcluded (not cdylib / host-only):
grainlify-stream— nocrate-typeinCargo.toml,testutils-only, produces no deployable wasmgrainlify-contracts—[[bin]]+rlib, not a cdylibEvidence requested by the issue
Verification commands (from issue)
Regression tests
scripts/tests/test_verify_wasm_artifacts.shexercisesverify-wasm-artifacts.shwith 8 synthetic-fixture test cases (no Rust toolchain needed):YAML syntax
(
Trueis Python's rendering of the YAMLonkeyword — correct for GitHub Actions.)Files changed
.github/workflows/build-reproducibility.ymlscripts/verify-wasm-artifacts.shscripts/tests/test_verify_wasm_artifacts.shNo existing tests were modified, weakened, or deleted.