Skip to content

[SO-338] Fingerprint the cached deployment-manager binary - #384

Open
greenpeppers100 wants to merge 1 commit into
stagingfrom
SO-338-fingerprint-deployment-manager-cache
Open

[SO-338] Fingerprint the cached deployment-manager binary#384
greenpeppers100 wants to merge 1 commit into
stagingfrom
SO-338-fingerprint-deployment-manager-cache

Conversation

@greenpeppers100

Copy link
Copy Markdown
Collaborator

The failure

Redeploy run 30772017011 died 10s in at Deploy contract on-chain:

Error: deploying env staging to testnet
Caused by:
    0: building Sui client for testnet
    1: MethodNotFound — "JSON-RPC on public fullnodes has been deprecated.
       Please migrate to gRPC or GraphQL endpoints."

Why it is not a code bug in staging

Neither building Sui client for nor the rpc= log field it printed exists anywhere in staging at afb124f. SO-337 (#383) replaced both: crates/sui-tx/src/sui_client.rs errors with building chain client for {network}, logs grpc_host=, and its module doc already reads "JSON-RPC (sui_sdk::SuiClient) is gone".

The run summary confirms it — Fetch prebuilt deployment-manager binary ✓, Build deployment manager skipped. And the asset it fetched:

$ gh api repos/ewitulsk/SuiOptions/releases/tags/deployment-manager-bin \
    --jq '.assets[] | "\(.name)  \(.created_at)"'
deploy-linux-x64  2026-07-26T01:22:41Z

Built 2026-07-26. SO-337 merged 2026-08-02. The workflow ran a pre-migration binary against fullnodes that had already turned JSON-RPC off, from a checkout whose source was already correct.

Root cause

The cache had no key. deploy-linux-x64 is a fixed asset name, --clobber-ed on every rebuild, and step 3 downloads it whenever it exists. rebuild_manager existed the whole time — and that is exactly the problem. A cache whose only invalidation is a human remembering to tick a box will go stale, and it went stale on the highest-stakes workflow in the repo.

The tempting patch is to re-run with rebuild_manager: true. That fixes today's redeploy and leaves the trap armed for the next crate change.

The fix

Content-address the cache. A new step fingerprints the binary's build closure from git object ids — no toolchain needed, exact by construction:

tools/deployment-manager   the crate
crates/                    every workspace-local dep (protocol-types,
                           runtime-config, cli-spec, sui-tx, deployments,
                           move-publish) + their path deps, which never
                           leave crates/
Cargo.toml, Cargo.lock     workspace members + pinned external versions,
                           incl. the sui-move-build rev that decides
                           whether a publish compiles

The asset becomes deploy-linux-x64-<fp>. A hit provably means "built from exactly this code"; a source change misses and rebuilds automatically, then uploads under the new name.

Out of the closure, deliberately:

  • services/ — nothing under it links into deploy, and it is where nearly all churn lives. Including it would force a ~15-minute rebuild on every redeploy and destroy the cache's value.
  • contracts/move-publish compiles Move at run time from the checkout, so Move is never baked into the binary.

Verified the closure claim: no crates/*/Cargo.toml has a path dep outside crates/.

Assets are pruned to the 10 newest so the prerelease does not grow without bound; that also retires the old unfingerprinted deploy-linux-x64. Losing an asset a concurrent run wanted just costs that run a rebuild, so best-effort deletion is fine.

rebuild_manager stays as an escape hatch for toolchain drift, with an updated description.

Verification

  • yaml.safe_load on the workflow passes.
  • The fingerprint command runs clean against staging: 541d13db69cbaa15.
  • gh release delete-asset <tag> <name> confirmed to exist in the installed gh.
  • No asset named deploy-linux-x64-541d13db69cbaa15 exists, so the first run after merge is a deliberate cache miss — it compiles the migrated deployment-manager from source, which is what unblocks the redeploy.
  • Runbook §1 deploy-compiler gate (cargo test -p deployment-manager --test deploy_build) running locally against afb124f; will report before re-running the redeploy.

Only .github/workflows/redeploy-contract.yml changes. No Rust, Move, or service code is touched.

redeploy-contract downloads a prebuilt `deploy` from a fixed prerelease
asset (deployment-manager-bin/deploy-linux-x64). The name is fixed and
`--clobber`-ed, so nothing tied the cached binary to the source it was
built from — a cache with no key.

That cost us run 30772017011. The asset was built 2026-07-26; SO-337
(#383) migrated the backend off JSON-RPC on 2026-08-02. The workflow
downloaded the pre-migration binary and ran it against fullnodes that
had already switched JSON-RPC off:

    0: building Sui client for testnet
    1: MethodNotFound — JSON-RPC on public fullnodes has been deprecated

while `crates/sui-tx/src/sui_client.rs` in the very same checkout was
already gRPC-only. `rebuild_manager` existed the whole time, and that is
the point: a cache whose only invalidation is a human remembering to
tick a box is not a cache.

So key the asset name on a fingerprint of the build closure — git object
ids of tools/deployment-manager, crates/, Cargo.toml and Cargo.lock. A
hit now provably means "built from exactly this code"; a source change
misses and rebuilds itself. `services/` and `contracts/` stay out:
nothing under services/ links into `deploy`, and move-publish compiles
Move at run time from the checkout, so neither is baked into the binary
and neither should evict the cache.

Assets are pruned to the 10 newest, which also retires the old
unfingerprinted one. rebuild_manager stays as an escape hatch for
toolchain drift.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
sui-options Ready Ready Preview Aug 2, 2026 11:25pm

Request Review

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