diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0a992a2..1a86149 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,9 +35,9 @@ jobs: steps: - uses: actions/checkout@v7 - name: Install current Rust toolchain - run: rustup toolchain install 1.98.1 --profile minimal + run: rustup toolchain install 1.99.0 --profile minimal - name: Verify lockfile is current - run: cargo +1.98.1 metadata --locked --format-version 1 >/dev/null + run: cargo +1.99.0 metadata --locked --format-version 1 >/dev/null msrv: name: MSRV (Rust 1.94.1) @@ -69,27 +69,27 @@ jobs: - uses: actions/checkout@v7 - name: Install current Rust toolchain run: | - rustup toolchain install 1.98.1 --profile minimal --component rustfmt - rustc +1.98.1 --version - cargo +1.98.1 --version + rustup toolchain install 1.99.0 --profile minimal --component rustfmt + rustc +1.99.0 --version + cargo +1.99.0 --version - name: Restore leptosfmt id: leptosfmt-cache uses: actions/cache@v6 with: path: ~/.cargo/bin/leptosfmt - key: ci-tool-${{ runner.os }}-leptosfmt-0.1.33-rust-1.98.1 + key: ci-tool-${{ runner.os }}-leptosfmt-0.1.33-rust-1.99.0 - name: Install Leptos formatter if: steps.leptosfmt-cache.outputs.cache-hit != 'true' - run: cargo +1.98.1 install leptosfmt --version 0.1.33 --locked + run: cargo +1.99.0 install leptosfmt --version 0.1.33 --locked - name: Generate canonical formatting id: format run: | - cargo +1.98.1 fmt --all + cargo +1.99.0 fmt --all while IFS= read -r -d '' f; do leptosfmt --rustfmt --stdin --quiet < "$f" > "$f.tmp" mv "$f.tmp" "$f" done < <(find live-search i18n-demo -name '*.rs' -print0) - cargo +1.98.1 fmt --all + cargo +1.99.0 fmt --all if git diff --quiet; then echo "changed=false" >> "$GITHUB_OUTPUT" @@ -121,9 +121,9 @@ jobs: - uses: actions/checkout@v7 - name: Install current Rust toolchain run: | - rustup toolchain install 1.98.1 --profile minimal --component clippy - rustc +1.98.1 --version - cargo +1.98.1 --version + rustup toolchain install 1.99.0 --profile minimal --component clippy + rustc +1.99.0 --version + cargo +1.99.0 --version - name: Restore Clippy build cache id: clippy-cache uses: actions/cache/restore@v6 @@ -133,17 +133,17 @@ jobs: target/debug/build target/debug/deps target/debug/examples - key: clippy-target-v3-${{ runner.os }}-rust-1.98.1-${{ hashFiles('Cargo.lock') }} + key: clippy-target-v3-${{ runner.os }}-rust-1.99.0-${{ hashFiles('Cargo.lock') }} restore-keys: | - clippy-target-v3-${{ runner.os }}-rust-1.98.1- + clippy-target-v3-${{ runner.os }}-rust-1.99.0- - name: Clippy run: | lint_args=(-D warnings -D clippy::pedantic -D clippy::nursery) - cargo +1.98.1 clippy --locked --workspace --all-targets -- "${lint_args[@]}" - cargo +1.98.1 clippy --locked -p live-search --features ssr --all-targets -- "${lint_args[@]}" - cargo +1.98.1 clippy --locked -p live-search --features ssr,otel --all-targets -- "${lint_args[@]}" - cargo +1.98.1 clippy --locked -p gateway-example --features otel --all-targets -- "${lint_args[@]}" - cargo +1.98.1 clippy --locked -p i18n-demo --features ssr --all-targets -- "${lint_args[@]}" + cargo +1.99.0 clippy --locked --workspace --all-targets -- "${lint_args[@]}" + cargo +1.99.0 clippy --locked -p live-search --features ssr --all-targets -- "${lint_args[@]}" + cargo +1.99.0 clippy --locked -p live-search --features ssr,otel --all-targets -- "${lint_args[@]}" + cargo +1.99.0 clippy --locked -p gateway-example --features otel --all-targets -- "${lint_args[@]}" + cargo +1.99.0 clippy --locked -p i18n-demo --features ssr --all-targets -- "${lint_args[@]}" - name: Save Clippy build cache if: >- success() && @@ -176,13 +176,13 @@ jobs: - uses: actions/checkout@v7 - name: Install current Rust toolchain run: | - rustup toolchain install 1.98.1 --profile minimal --target wasm32-unknown-unknown - rustc +1.98.1 --version - cargo +1.98.1 --version + rustup toolchain install 1.99.0 --profile minimal --target wasm32-unknown-unknown + rustc +1.99.0 --version + cargo +1.99.0 --version # Use `build`, not `check`: Rust 1.96 stopped passing wasm-ld's # --allow-undefined implicitly, so only a real link exercises that policy. - name: Link hydration build - run: cargo +1.98.1 build --locked -p "${{ matrix.package }}" --target wasm32-unknown-unknown --features hydrate --lib + run: cargo +1.99.0 build --locked -p "${{ matrix.package }}" --target wasm32-unknown-unknown --features hydrate --lib unit-tests: name: Unit tests @@ -204,16 +204,16 @@ jobs: uses: actions/cache@v6 with: path: .sccache/unit-tests - key: sccache-unit-v3-${{ runner.os }}-rust-1.98.1-${{ hashFiles('Cargo.lock', '**/Cargo.toml') }} + key: sccache-unit-v3-${{ runner.os }}-rust-1.99.0-${{ hashFiles('Cargo.lock', '**/Cargo.toml') }} restore-keys: | - sccache-unit-v3-${{ runner.os }}-rust-1.98.1- + sccache-unit-v3-${{ runner.os }}-rust-1.99.0- - name: Install current Rust toolchain run: | - rustup toolchain install 1.98.1 --profile minimal - rustc +1.98.1 --version - cargo +1.98.1 --version + rustup toolchain install 1.99.0 --profile minimal + rustc +1.99.0 --version + cargo +1.99.0 --version - name: Run library tests - run: cargo +1.98.1 test --locked --workspace --lib + run: cargo +1.99.0 test --locked --workspace --lib - name: Show sccache stats if: always() run: ${SCCACHE_PATH} --show-stats @@ -226,8 +226,8 @@ jobs: id-token: write uses: codeandsolder/ci-workflows/.github/workflows/rust-sccache.yml@main with: - command: cargo +1.98.1 test --locked --workspace --lib - rust-toolchain: "1.98.1" + command: cargo +1.99.0 test --locked --workspace --lib + rust-toolchain: "1.99.0" rustflags: "-C target-cpu=x86-64-v2" audit: @@ -239,18 +239,18 @@ jobs: - uses: actions/checkout@v7 - name: Install current Rust toolchain run: | - rustup toolchain install 1.98.1 --profile minimal - rustc +1.98.1 --version - cargo +1.98.1 --version + rustup toolchain install 1.99.0 --profile minimal + rustc +1.99.0 --version + cargo +1.99.0 --version - name: Restore cargo-audit id: cargo-audit-cache uses: actions/cache@v6 with: path: ~/.cargo/bin/cargo-audit - key: ci-tool-${{ runner.os }}-cargo-audit-0.22.2-rust-1.98.1 + key: ci-tool-${{ runner.os }}-cargo-audit-0.22.2-rust-1.99.0 - name: Install cargo-audit if: steps.cargo-audit-cache.outputs.cache-hit != 'true' - run: cargo +1.98.1 install cargo-audit --version 0.22.2 --locked + run: cargo +1.99.0 install cargo-audit --version 0.22.2 --locked - name: Audit dependencies run: cargo audit @@ -273,14 +273,14 @@ jobs: uses: actions/cache@v6 with: path: .sccache/leptos-build - key: sccache-leptos-v2-${{ runner.os }}-rust-1.98.1-${{ hashFiles('Cargo.lock', '**/Cargo.toml') }} + key: sccache-leptos-v2-${{ runner.os }}-rust-1.99.0-${{ hashFiles('Cargo.lock', '**/Cargo.toml') }} restore-keys: | - sccache-leptos-v2-${{ runner.os }}-rust-1.98.1- + sccache-leptos-v2-${{ runner.os }}-rust-1.99.0- - name: Install current Rust toolchain run: | - rustup toolchain install 1.98.1 --profile minimal --target wasm32-unknown-unknown - rustc +1.98.1 --version - cargo +1.98.1 --version + rustup toolchain install 1.99.0 --profile minimal --target wasm32-unknown-unknown + rustc +1.99.0 --version + cargo +1.99.0 --version - name: Restore Leptos build tools id: leptos-tools-cache uses: actions/cache@v6 @@ -288,22 +288,22 @@ jobs: path: | ~/.cargo/bin/cargo-leptos ~/.cargo/bin/stylance - key: ci-tools-${{ runner.os }}-cargo-leptos-0.3.7-stylance-0.8.4-rust-1.98.1 + key: ci-tools-${{ runner.os }}-cargo-leptos-0.3.7-stylance-0.8.4-rust-1.99.0 - name: Install build tools if: steps.leptos-tools-cache.outputs.cache-hit != 'true' run: | - cargo +1.98.1 install cargo-leptos --version 0.3.7 --locked - cargo +1.98.1 install stylance-cli --version 0.8.4 --locked + cargo +1.99.0 install cargo-leptos --version 0.3.7 --locked + cargo +1.99.0 install stylance-cli --version 0.8.4 --locked - name: Build live-search run: | - cargo +1.98.1 leptos build --release -p live-search + cargo +1.99.0 leptos build --release -p live-search mkdir -p target/site/pkg stylance live-search --output-file target/site/pkg/live-search.css find target/site/pkg -maxdepth 1 -type f -name '*.js' -size +0c -print -quit | grep -q . find target/site/pkg -maxdepth 1 -type f -name '*.wasm' -size +0c -print -quit | grep -q . test -s target/site/pkg/live-search.css - name: Build i18n-demo - run: cargo +1.98.1 leptos build --release -p i18n-demo + run: cargo +1.99.0 leptos build --release -p i18n-demo - name: Show sccache stats if: always() run: ${SCCACHE_PATH} --show-stats @@ -361,14 +361,14 @@ jobs: uses: actions/cache@v6 with: path: .sccache/e2e - key: sccache-e2e-v2-${{ runner.os }}-rust-1.98.1-${{ hashFiles('Cargo.lock', '**/Cargo.toml') }} + key: sccache-e2e-v2-${{ runner.os }}-rust-1.99.0-${{ hashFiles('Cargo.lock', '**/Cargo.toml') }} restore-keys: | - sccache-e2e-v2-${{ runner.os }}-rust-1.98.1- + sccache-e2e-v2-${{ runner.os }}-rust-1.99.0- - name: Install current Rust toolchain run: | - rustup toolchain install 1.98.1 --profile minimal --target wasm32-unknown-unknown - rustc +1.98.1 --version - cargo +1.98.1 --version + rustup toolchain install 1.99.0 --profile minimal --target wasm32-unknown-unknown + rustc +1.99.0 --version + cargo +1.99.0 --version - name: Restore E2E build tools id: e2e-tools-cache uses: actions/cache@v6 @@ -376,12 +376,12 @@ jobs: path: | ~/.cargo/bin/wasm-bindgen ~/.cargo/bin/stylance - key: ci-tools-${{ runner.os }}-wasm-bindgen-cli-0.2.128-stylance-0.8.4-rust-1.98.1 + key: ci-tools-${{ runner.os }}-wasm-bindgen-cli-0.2.128-stylance-0.8.4-rust-1.99.0 - name: Install E2E build tools if: steps.e2e-tools-cache.outputs.cache-hit != 'true' run: | - cargo +1.98.1 install wasm-bindgen-cli --version 0.2.128 --locked - cargo +1.98.1 install stylance-cli --version 0.8.4 --locked + cargo +1.99.0 install wasm-bindgen-cli --version 0.2.128 --locked + cargo +1.99.0 install stylance-cli --version 0.8.4 --locked - name: Configure Chrome shell: bash run: | @@ -398,7 +398,7 @@ jobs: run: bash scripts/test-e2e.sh - name: Verify SQLx OpenTelemetry span parenting run: >- - cargo +1.98.1 test --release --locked -p e2e-tests --test otel_db_test + cargo +1.99.0 test --release --locked -p e2e-tests --test otel_db_test --features otel-tests -- --test-threads=1 --nocapture - name: Show sccache stats if: always() diff --git a/README.md b/README.md index e789032..be58f98 100644 --- a/README.md +++ b/README.md @@ -209,7 +209,7 @@ shutdown wiring for active connections. ## Build and validation -Basic static/test pass on the default Rust 1.98.1 toolchain: +Basic static/test pass on the default Rust 1.99.0 toolchain: ```bash cargo check --workspace --all-targets @@ -264,7 +264,7 @@ formatting, native Clippy feature combinations, real WASM hydration linking, workspace library tests, `cargo audit`, production Leptos builds, all three Docker images, and real Chromium-backed E2E tests. -Current-stable jobs use Rust **1.98.1**. A separate **1.94.1 MSRV** lane checks +Current-stable jobs use Rust **1.99.0**. A separate **1.94.1 MSRV** lane checks both the native workspace and hydration crates, so adopting new stable APIs does not silently raise the advertised compatibility floor. Cargo resolver 3 makes new dependency resolution MSRV-aware. CI also uses Cargo 1.97+'s diff --git a/SKILL.md b/SKILL.md index dd6b045..1c42c90 100644 --- a/SKILL.md +++ b/SKILL.md @@ -24,7 +24,7 @@ fix this document in the same change. The workspace uses Edition 2024 with resolver 3. Rust **1.94** remains the compatibility floor/MSRV and is tested on patched **1.94.1**. Normal development, -current-stable CI, and production builds use patched **Rust 1.98.1**. Newer +current-stable CI, and production builds use **Rust 1.99.0**. Newer stable Rust versions do not by themselves justify raising the MSRV; the oldest supported compiler and the preferred compiler for shipping builds are separate policies. @@ -413,7 +413,7 @@ docker compose --profile dev up --build \ The maintained GitHub Actions workflow should cover: - a dedicated patched-MS​​RV lane for Rust 1.94.1, separate from current-stable validation, -- native workspace/all-target Clippy plus supported native feature combinations on Rust 1.98.1, +- native workspace/all-target Clippy plus supported native feature combinations on Rust 1.99.0, - SSR and hydration feature matrices, - a real `wasm32-unknown-unknown` link on current stable, not only `cargo check`, - the `otel` feature compilation, diff --git a/ci/leptosfmt.Dockerfile b/ci/leptosfmt.Dockerfile index 58be385..8b76449 100644 --- a/ci/leptosfmt.Dockerfile +++ b/ci/leptosfmt.Dockerfile @@ -8,7 +8,8 @@ FROM rust:1.98-bookworm@sha256:93ce27a88655056a51dbdd8f5f2d7ddc071c7b0070fb288a37b5a285fc83971e AS build # Install leptosfmt into a global cargo bin dir so the runtime layer can COPY it. -RUN cargo install leptosfmt --locked +RUN rustup toolchain install 1.99.0 --profile minimal && \ + RUSTUP_TOOLCHAIN=1.99.0 cargo install leptosfmt --locked # Slim runtime: same digest, only the cargo bin dir copied. FROM rust:1.98-bookworm@sha256:93ce27a88655056a51dbdd8f5f2d7ddc071c7b0070fb288a37b5a285fc83971e diff --git a/e2e-tests/src/common/json.rs b/e2e-tests/src/common/json.rs index 1186d72..4341cb4 100644 --- a/e2e-tests/src/common/json.rs +++ b/e2e-tests/src/common/json.rs @@ -28,7 +28,7 @@ mod proptests { } proptest! { - /// SearchResult round-trips through serde_json losslessly. + /// `SearchResult` round-trips through `serde_json` losslessly. #[test] fn search_result_json_roundtrip(result in arb_search_result()) { let json = serde_json::to_value(&result) diff --git a/gateway.Dockerfile b/gateway.Dockerfile index 4c49cd9..2052ac0 100644 --- a/gateway.Dockerfile +++ b/gateway.Dockerfile @@ -3,10 +3,11 @@ # Multi-stage build with cargo-chef for reproducible dependency caching # across the whole workspace. FROM rust:1.98.1-bookworm@sha256:93ce27a88655056a51dbdd8f5f2d7ddc071c7b0070fb288a37b5a285fc83971e AS chef -# The official 1.98 image carries 1.98.0; install the patched stable compiler -# explicitly so production builds do not stay on a known superseded point release. -RUN rustup toolchain install 1.98.1 --profile minimal -ENV RUSTUP_TOOLCHAIN=1.98.1 +# Keep the reproducible Bookworm base pinned by digest, then install the +# repository's current stable compiler explicitly so Docker image publication +# lag cannot leave production builds on an older Rust release. +RUN rustup toolchain install 1.99.0 --profile minimal +ENV RUSTUP_TOOLCHAIN=1.99.0 RUN cargo install cargo-chef --locked WORKDIR /build @@ -16,6 +17,9 @@ RUN cargo chef prepare --recipe-path recipe.json FROM chef AS builder COPY --from=planner /build/recipe.json recipe.json +# The workspace patches crates.io dependencies to local sources. Those path +# dependencies must exist while cargo-chef cooks the dependency layer. +COPY third-party /build/third-party # Match the final package selection exactly so Cargo can reuse the cooked # library + binary dependency graph after the real sources are copied in. RUN cargo chef cook --recipe-path recipe.json --locked --release \ diff --git a/i18n-demo.Dockerfile b/i18n-demo.Dockerfile index 6d889a8..520b724 100644 --- a/i18n-demo.Dockerfile +++ b/i18n-demo.Dockerfile @@ -2,10 +2,11 @@ # # Multi-stage build for the i18n-demo Leptos crate. FROM rust:1.98.1-bookworm@sha256:93ce27a88655056a51dbdd8f5f2d7ddc071c7b0070fb288a37b5a285fc83971e AS chef -# The official 1.98 image carries 1.98.0; install the patched stable compiler -# explicitly so production builds do not stay on a known superseded point release. -RUN rustup toolchain install 1.98.1 --profile minimal -ENV RUSTUP_TOOLCHAIN=1.98.1 +# Keep the reproducible Bookworm base pinned by digest, then install the +# repository's current stable compiler explicitly so Docker image publication +# lag cannot leave production builds on an older Rust release. +RUN rustup toolchain install 1.99.0 --profile minimal +ENV RUSTUP_TOOLCHAIN=1.99.0 RUN cargo install cargo-chef --locked WORKDIR /build @@ -17,6 +18,9 @@ FROM chef AS builder RUN rustup target add wasm32-unknown-unknown && \ cargo install wasm-bindgen-cli --version 0.2.128 --locked COPY --from=planner /build/recipe.json recipe.json +# The workspace patches crates.io dependencies to local sources. Those path +# dependencies must exist while cargo-chef cooks the dependency layer. +COPY third-party /build/third-party # Keep wasm/native dependency cooks scoped to this crate. A workspace-wide wasm # cook enables native networking dependencies from unrelated members. RUN cargo chef cook --recipe-path recipe.json --locked --release \ diff --git a/live-search.Dockerfile b/live-search.Dockerfile index 3db710e..ac64296 100644 --- a/live-search.Dockerfile +++ b/live-search.Dockerfile @@ -6,10 +6,11 @@ # 3. builder: cargo chef cook the recipe (cached dependency build), # then copy source and build the binary. FROM rust:1.98.1-bookworm@sha256:93ce27a88655056a51dbdd8f5f2d7ddc071c7b0070fb288a37b5a285fc83971e AS chef -# The official 1.98 image carries 1.98.0; install the patched stable compiler -# explicitly so production builds do not stay on a known superseded point release. -RUN rustup toolchain install 1.98.1 --profile minimal -ENV RUSTUP_TOOLCHAIN=1.98.1 +# Keep the reproducible Bookworm base pinned by digest, then install the +# repository's current stable compiler explicitly so Docker image publication +# lag cannot leave production builds on an older Rust release. +RUN rustup toolchain install 1.99.0 --profile minimal +ENV RUSTUP_TOOLCHAIN=1.99.0 RUN cargo install cargo-chef --locked WORKDIR /build @@ -22,6 +23,9 @@ RUN rustup target add wasm32-unknown-unknown && \ cargo install wasm-bindgen-cli --version 0.2.128 --locked && \ cargo install stylance-cli --locked COPY --from=planner /build/recipe.json recipe.json +# The workspace patches crates.io dependencies to local sources. Those path +# dependencies must exist while cargo-chef cooks the dependency layer. +COPY third-party /build/third-party # Stylance's import_style proc macro reads this file at compile time. cargo-chef # recipes contain Rust manifests/skeletons, not arbitrary CSS assets, so make # the stylesheet available before the dependency cook as well as the real build. diff --git a/rust-toolchain.toml b/rust-toolchain.toml index d6b865a..5a14e18 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.98.1" +channel = "1.99.0" components = ["rustfmt", "clippy"] targets = ["wasm32-unknown-unknown"] \ No newline at end of file