Skip to content

Upgrade to Rust 1.98.1 and align dependencies with EdgeZero - #1123

Draft
aram356 wants to merge 7 commits into
mainfrom
chore/upgrade-rust-198-deps
Draft

Upgrade to Rust 1.98.1 and align dependencies with EdgeZero#1123
aram356 wants to merge 7 commits into
mainfrom
chore/upgrade-rust-198-deps

Conversation

@aram356

@aram356 aram356 commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Aligns the toolchain and shared dependency pins with EdgeZero PR stackpop/edgezero#366, so both workspaces resolve the same major versions instead of fighting each other.

The Fastly adapter does not build on this branch. That is a single external blocker, tracked in #1122 and detailed at the bottom. Everything else — core, Axum, Cloudflare, Spin, CLI — compiles, lints and tests clean.

Toolchain

Tool From To
Rust 1.95.0 1.98.1
Node 24.12.0 24.20.0
Fastly CLI 15.1.0 16.0.0
Viceroy 0.17.0 0.21.0
wasmtime 44.0.1 48.0.1

CI derives every one of these from .tool-versions, so only that file and rust-toolchain.toml pin them — no workflow changes needed.

EdgeZero

Moves from tag = "v0.0.7" to rev = 40c52e3f (the head of #366). Deliberately a rev, not a tag: the latest release, v0.0.8, still carries the 1.95 toolchain and the previous majors, so it would contradict every pin below. The comment at the pin says to restore a tag once #366 merges.

Dependency majors

Matched to #366: fastly and log-fastly 0.12 → 0.13, spin-sdk ~6.0 → ~7.0, validator 0.20 → 0.21, sha2 0.10 → 0.11.

brotli stays at 8, for the reason #366 records and measures: async-compression still resolves brotli 8, so taking 9 on the direct dependency adds a second decompressor stack rather than replacing one.

Two further majors this workspace needs but #366 did not. sha2 0.11 moves RustCrypto to hybrid_array, and the ecosystem has to cross together: hmac 0.12 → 0.13 and chacha20poly1305 0.10 → 0.11. Without them, XChaCha20Poly1305::new receives an Array where it expects a GenericArray.

Source changes — six lines, no lint suppressions

Every fix addresses the actual API change. Nothing is silenced with #[allow].

  • new_from_slice moved from Mac to KeyInit in hmac 0.13 — ec/generation.rs and s3_sigv4.rs bring the trait into scope with as _.
  • Array does not implement LowerHex as GenericArray did — settings_data.rs formats via hex::encode. (hex is already a dependency, already used for exactly this nearby. Hand-rolling hex is a trap: it trips indexing_slicing, then as-truncation, then arithmetic_side_effects in turn.)
  • Array::from_slice is deprecated in favour of TryFrom, which is an error under -D warnings. In http_util.rs the encode path builds a fixed [u8; 24] and converts infallibly via From; the decode path takes a runtime slice and uses TryFrom, returning None on a mismatch to match the function's existing Option contract — replacing a path that would previously have panicked.
  • Rust 1.98 flags two redundant importspublisher.rs (std::io::Write) and cli/src/run.rs (clap::Parser) each import the trait at file scope, and the test module's use super::* already brings it in, so the module's own as _ copy is unused. Confirmed new to the toolchain rather than pre-existing: clippy on main under 1.95 is clean against the identical pairs.

getrandom

sha2 0.11 pulls crypto-common 0.2, which depends on getrandom 0.4 without enabling its browser RNG feature. On wasm32-unknown-unknown that is a hard compile_error!.

A transitive dependency's features can only be enabled by declaring it directly, so getrandom_04 is a renamed-package entry alongside the existing getrandom 0.2 line. The repo already does exactly this for 0.2 with features = ["js"]; 0.4 renamed that feature to wasm_js, which is why the two need separate entries. Both majors are load-bearing.

Behaviour is unchanged, and this was verified rather than assumed

hmac 0.13 could plausibly have changed digests for keys shorter than the block size — which would silently invalidate every persisted EC ID and S3 SigV4 signature. Built scratch crates against both versions and compared:

0.12  short key (18 bytes): 6de2581fb61f36512e7d6f6f848a5f45586cc0502f5959302be94168ca2891d8
0.13  short key (18 bytes): 6de2581fb61f36512e7d6f6f848a5f45586cc0502f5959302be94168ca2891d8
0.12  block-length (64):    54be2c66676012b3a6c28720fd9ad115e0634b75407fcebcb9225f9dfd951f4a
0.13  block-length (64):    54be2c66676012b3a6c28720fd9ad115e0634b75407fcebcb9225f9dfd951f4a

Byte-identical. Existing identities remain valid.

Documentation

Viceroy install command updated to 0.21.0 in the getting-started, testing and error-reference guides, the integration-tests README, and three scripts that name it in their prerequisites.

The getting-started prerequisites keep their {{RUST_VERSION}} and {{NODEJS_VERSION}} placeholders. docs/.vitepress/config.mts installs a markdown hook that reads .tool-versions and substitutes {{<TOOL>_VERSION}} for every tool listed there, so those lines track the pins automatically and need no edit. Verified against a real npm run build: the rendered HTML reads "Rust 1.98.1", "NodeJS 24.20.0" and "Fastly 16.0.0".

docs/superpowers/** keeps its 1.95 and 0.17.0 mentions: dated design records describing the stack as it stood when each was written. Same exclusion #366 made.

The blocker: esi pins fastly ^0.12 (#1122)

esi 0.7.2 declares fastly = "^0.12" while EdgeZero requires 0.13. Both land in trusted-server-adapter-fastly, and esi_assembly.rs passes fastly::http::Response/Request across that boundary, so it sees two incompatible copies of the same types. ESI is unconditional there, not feature-gated.

The fix is one line and needs no source changes to esi. Cloning fastly/esi at v0.7.2 and changing only the manifest range to ^0.13 compiles clean, and with that patched in locally the entire workspace builds, Fastly adapter included.

Upstream main still reads ^0.12, and no open PR addresses it — fastly/esi#60 is the v0.7.2 release bump, touching only the workspace version and lockfile. #1122 lays out the two paths (upstream PR and wait, or carry it on the existing stackpop/esi fork behind [patch.crates-io]).

Closes

Closes #1124

Depends on #1122 for the temporary esi patch — that one stays open until the range bump is released upstream and the patch can be dropped.

Test plan

Verified on rustc 1.98.1, Node 24.20.0, Viceroy 0.21.0:

  • cargo fmt --all -- --check
  • cargo clippy-axum, clippy-cloudflare, clippy-cloudflare-wasm, clippy-spin-native, clippy-spin-wasm — all clean under -D warnings
  • cargo test-axum — 38 passed
  • cargo test-cloudflare — 40 passed
  • cargo test-spin — 80 passed
  • cargo test --package trusted-server-cli --target aarch64-apple-darwin — 209 passed, plus clippy --all-targets -D warnings
  • JS: 893 tests across 45 files, plus npm run format
  • Docs: npm run format
  • HMAC output compared byte-for-byte between 0.12 and 0.13 (above)

Fastly gates — pass, but only with the esi fix applied locally. They cannot run in CI until #1122 is resolved. With [patch.crates-io] pointing at an esi clone whose only change is fastly = "^0.13":

  • cargo clippy-fastly — clean under -D warnings
  • cargo test-fastly166 adapter (ESI assembly included) + 2290 core + 2 js + 21 openrtb + 3 doctests, 0 failed, under Viceroy 0.21.0

That patch is not committed here. It exists only to prove the upgrade is sound and that #1122 is the sole thing standing in the way.

Review notes

The Fastly gates will be red in CI until #1122 is resolved, so that decision gates this merge. Everything else is green, and the run above shows the Fastly side passes the moment esi's range moves.

The getrandom_04 renamed-package entry is the one piece of unusual wiring and the thing most worth a second opinion.

Match the toolchain and shared dependency pins to EdgeZero PR #366 so
both workspaces resolve the same major versions.

Toolchain: Rust 1.95.0 to 1.98.1, Node 24.12.0 to 24.20.0, Fastly CLI
15.1.0 to 16.0.0, Viceroy 0.17.0 to 0.21.0, wasmtime 44.0.1 to 48.0.1.
CI derives each from `.tool-versions`, so only that file and
`rust-toolchain.toml` pin them.

EdgeZero moves from tag v0.0.7 to the PR #366 head revision. The latest
tag, v0.0.8, still carries the 1.95 toolchain and the previous majors,
so it would contradict the pins below. Restore a tag once #366 merges.

Shared majors: fastly and log-fastly 0.12 to 0.13, spin-sdk ~6.0 to
~7.0, validator 0.20 to 0.21, sha2 0.10 to 0.11. brotli stays at 8 for
the reason recorded in #366: async-compression still resolves 8, so
taking 9 adds a second decompressor stack rather than replacing one.

sha2 0.11 moves RustCrypto to `hybrid_array`, which forces two further
majors this workspace needs but #366 did not: hmac 0.12 to 0.13 and
chacha20poly1305 0.10 to 0.11. Their fallout is three lines:

- `new_from_slice` moved from `Mac` to `KeyInit`, so `ec/generation.rs`
  and `s3_sigv4.rs` bring that trait into scope. HMAC output is
  unchanged, verified byte-for-byte against 0.12 for both a short key
  and a block-length key, so persisted EC IDs and SigV4 signatures stay
  valid.
- `Array` does not implement `LowerHex` as `GenericArray` did, so
  `settings_data.rs` formats via `hex::encode`.

sha2 0.11 also pulls crypto-common 0.2, which depends on getrandom 0.4.
That line renamed the browser RNG feature from `js` to `wasm_js`, so
the Cloudflare target needs a second getrandom entry to enable it.

The Fastly adapter does not build on this branch: `esi` 0.7.2 pins
fastly ^0.12 while EdgeZero requires 0.13, and both meet in
`esi_assembly.rs`. Upstream `fastly/esi` main is still on ^0.12.
Point the Viceroy install command at 0.21.0 in the getting-started,
testing and error-reference guides, the integration-tests README, and
the three scripts that name it in their prerequisites.

Fill in the Rust and NodeJS versions in the getting-started
prerequisites. Both were `{{RUST_VERSION}}` / `{{NODEJS_VERSION}}`
placeholders with no substitution step anywhere in the repo, so the
published page rendered the braces literally.

`docs/superpowers/**` keeps its 1.95 and 0.17.0 mentions: those are
dated design records describing the stack as it stood when each was
written.
`hybrid_array` deprecates `from_slice` in favour of `TryFrom`, which is
an error under the workspace's `-D warnings` clippy gate.

The encode path builds a fixed `[u8; 24]`, so it converts infallibly
via `XNonce::from`. The decode path takes a runtime slice, so it uses
`XNonce::try_from` and returns `None` on a mismatch, matching the
function's existing `Option` contract; the preceding length check
already guarantees 24 bytes, so this is unreachable in practice and
replaces a path that would previously have panicked.

Both conversions yield an owned `XNonce` where `from_slice` yielded a
reference, so the three use sites borrow explicitly.
@aram356 aram356 added dependencies Pull requests that update a dependency file rust Pull requests that update rust code edgezero EdgeZero migration and removed dependencies Pull requests that update a dependency file rust Pull requests that update rust code edgezero EdgeZero migration labels Sep 6, 2026
@aram356
aram356 marked this pull request as draft September 7, 2026 00:04
@aram356 aram356 self-assigned this Sep 7, 2026
`publisher.rs` imports `std::io::Write` at file scope, and the test
module's `use super::*` already brings it in, so the module's own
`Write as _` is redundant. Rust 1.98 reports it as an unused import,
which is an error under the workspace's `-D warnings` gate.

Confirmed new to the toolchain rather than pre-existing: clippy on
`main` under 1.95 is clean against the identical pair of imports.
`run.rs` imports `Parser` at file scope, and the test module's
`use super::*` already brings it in, so the module's own
`Parser as _` is redundant. Same shape as the `publisher.rs` case:
new under Rust 1.98, and an error under `-D warnings`.

Missed in the first local pass because `cargo check` on the CLI runs
neither `--all-targets` nor `-D warnings`; CI's clippy does both.
@aram356

aram356 commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

CI status after the two Rust 1.98 unused-import fixes.

Passing: cross-adapter parity, cloudflare (native + wasm32-unknown-unknown), spin (native + wasm32-wasip1), ts CLI (native), vitest, format-typescript, format-docs, CodeQL.

Failing — all four for the same reason: cargo fmt (the job also runs cargo clippy-fastly), cargo test, cargo test (axum native) (the job also runs the Fastly WASM release build), and prepare integration artifacts.

Each fails with the same two errors at the same two lines:

error[E0308]: mismatched types
   --> crates/trusted-server-adapter-fastly/src/esi_assembly.rs:96:9
error[E0631]: type mismatch in closure arguments
   --> crates/trusted-server-adapter-fastly/src/esi_assembly.rs:124:65

That is #1122 and nothing else — no other failure mode appears in any of the four logs. Every job that does not build the Fastly adapter is green.

Locally, with esi patched to fastly = "^0.13" (no source change to esi), cargo clippy-fastly is clean and cargo test-fastly passes 166 adapter + 2290 core + 2 js + 21 openrtb + 3 doctests. So these four go green the moment #1122 lands.

`esi` 0.7.2 pins `fastly = "^0.12"` while EdgeZero requires 0.13. Both
land in `trusted-server-adapter-fastly`, and `esi_assembly.rs` passes
`fastly::Request` and `Response` across that boundary, so the two
copies meet and the adapter fails to compile.

The fork changes only the version ranges, in the library and the six
examples that pin `fastly` themselves. No source changes: the crate
compiles and its suite passes unmodified against 0.13.

`fastly` 0.12 now drops out of the graph entirely, leaving one copy.

Temporary. Drop this patch once the range bump is released upstream;
tracked in #1122.
@aram356

aram356 commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

All CI checks pass with the esi patch in place.

Every job that was failing on the esi type conflict is now green: cargo fmt (which also runs clippy-fastly), cargo test, cargo test (axum native) (which also builds the Fastly WASM release), and prepare integration artifacts. The integration test jobs, which previously skipped because no artifacts were produced, now run.

The patch points at stackpop/esi@75bfbb396, branched from upstream v0.7.2. It changes only version ranges — the library plus the six examples that pin fastly themselves — with no source changes. esi's own suite passes against 0.13: 163 tests, 0 failed, under Viceroy 0.21.0.

fastly 0.12 is gone from the graph; one copy remains.

The patch is temporary and commented as such. It should be dropped once the range bump is released upstream — #1122 tracks that.

`{{RUST_VERSION}}` and `{{NODEJS_VERSION}}` were replaced with literal
versions on the mistaken belief that nothing substituted them. VitePress
does: `docs/.vitepress/config.mts` installs a markdown hook that reads
`.tool-versions` and replaces `{{<TOOL>_VERSION}}` for every tool listed
there. `{{FASTLY_VERSION}}`, four lines below in the same file, was
already relying on it.

Hardcoding the numbers dropped the guide out of that mechanism, so it
would have silently gone stale at the next toolchain bump. The
placeholders now resolve from the versions updated earlier in this
branch; verified against a real `npm run build`, whose rendered HTML
reads "Rust 1.98.1", "NodeJS 24.20.0" and "Fastly 16.0.0" with no
placeholder left unsubstituted.
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.

Upgrade to Rust 1.98.1 and align dependencies with EdgeZero

1 participant