feat(release): publish Rust contract bindings - #38
Conversation
Keep Cargo consumers on the same canonical ABI and release train as the npm package. Relates to ENG-4070.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
| readme = "README.md" | ||
| keywords = ["ethereum", "solidity", "abi", "bindings", "credible-layer"] | ||
| publish = ["crates-io"] | ||
| include = ["src/**", "abi/StateOracle.json", "README.md", "RELEASING.md"] |
There was a problem hiding this comment.
This allowlist leaves both repository license files out of the published crate. I confirmed the package contains the manifest, documentation, ABI, and source, but neither license text. Please include both files so consumers receive the terms declared by the manifest.
| version: nightly | ||
| - name: Setup Rust | ||
| run: | | ||
| rustup toolchain install stable --profile minimal --component clippy,rustfmt --no-self-update |
There was a problem hiding this comment.
The manifest promises Rust 1.85, but CI only tests the moving stable toolchain. A newer language feature or dependency can raise the minimum while every check stays green. Please add a Rust 1.85 build so the published minimum remains enforced.
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| id-token: write |
There was a problem hiding this comment.
This permission is available to every step in the job, including compilation and package verification of registry dependencies. Dependency code executed there can request the same OIDC identity intended for publishing. Please move verification to a job without token permission and keep the privileged publish job minimal.
| - name: Authenticate to crates.io | ||
| if: steps.published.outputs.exists != 'true' | ||
| id: crates-io-auth | ||
| uses: rust-lang/crates-io-auth-action@v1 |
There was a problem hiding this comment.
This privileged job follows mutable tags for checkout, artifact download, and authentication. Pin those actions to reviewed commit SHAs so a later tag update cannot gain release authority without a repository change.
| name: credible-layer-contracts-artifacts | ||
| path: artifacts/ | ||
| release-npm: | ||
| release-npm-verify: |
There was a problem hiding this comment.
The Cargo verification job is the only place that rejects a generated StateOracle ABI which differs from the committed Rust snapshot, but this npm job runs in parallel and can still publish that mismatched artifact. Please make npm packaging depend on the ABI verification, or repeat the comparison here, so npm and Cargo cannot ship different contract boundaries.
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| submodules: recursive |
There was a problem hiding this comment.
The release packages trust the output of this job, so its actions are part of the publishing boundary even though this job has no token permission. A moved checkout, Foundry, or upload action tag can still change what npm and the GitHub release publish. Please pin these actions and the Foundry version used to generate release artifacts.
| run: cargo publish --manifest-path bindings/rust/Cargo.toml --no-verify | ||
| release-github: | ||
| needs: create-artifacts | ||
| runs-on: ubuntu-latest |
There was a problem hiding this comment.
This job still only waits for artifact generation, so a tag that does not match either package manifest can create a public GitHub release while the version checks fail in parallel. That contradicts the documented fail before publishing behavior and leaves a release for a version the packages do not declare. Please make this job wait for both package verification jobs before calling gh release create.
| uses: foundry-rs/foundry-toolchain@908c540300062bd5a7e473851cdb4282204cee09 # v1 | ||
| with: | ||
| version: nightly | ||
| version: v1.7.1 |
There was a problem hiding this comment.
Pinning Foundry here does not pin the Solidity compiler used by forge build. foundry.toml leaves solc unset, auto detection is enabled, and these contracts use a caret pragma, so a clean runner selects the newest allowed compiler and that choice can move as new versions are released. The canonical ABI is therefore not derived from a fully fixed toolchain. Please pin the Solc version used for artifact generation as well.
| self.assertIn('cp "${INTERFACES}/IStateOracleV1.json"', script) | ||
| self.assertIn('cp "${INTERFACES}/IStateOracleV2.json"', script) | ||
|
|
||
| def test_state_oracle_release_mapping_preserves_supported_abis(self): |
There was a problem hiding this comment.
This test does not preserve either ABI. It only checks the table and module names, so an additive edit to the frozen V1 interface passes here and the compatibility job only emits a warning. V1 matches the published 0.2.0 ABI today, but nothing prevents it from drifting later. Please compare the complete V1 ABI with the 0.2.0 release artifact or a pinned digest.
phylax-ci
left a comment
There was a problem hiding this comment.
Blocking: shell/create_artifacts.sh:73-85 regenerates and overwrites the historical V1 snapshot from the editable interface, while test/release/test_release_workflow.py:263-274 only asserts documentation and module names. Because the compatibility job treats additive ABI changes as warnings, an added V1 function or event can silently change the Rust binding advertised for the already-published 0.2.0 boundary. @fredo Next step: add one CI assertion that compares the complete normalized V1 ABI against the v0.2.0 release artifact and fails on any mismatch.
Implements ENG-4070.
Publishes Alloy
StateOraclebindings from the canonical contract ABI through crates.io while keeping npm, Cargo, and tag versions aligned. Adds OIDC trusted publishing and drift checks so public-crate and repository-pinned consumers share the same source-owned contract boundary.