diff --git a/.gitea/workflows/build-and-test.yml b/.gitea/workflows/build-and-test.yml index 5350cd3..0945317 100644 --- a/.gitea/workflows/build-and-test.yml +++ b/.gitea/workflows/build-and-test.yml @@ -117,12 +117,20 @@ jobs: # The act image ships Node but no Rust. Pinned to the workspace # rust-version so CI, the Android image, and local builds agree — a # floating toolchain turns an unrelated push into a mystery failure. + # + # The component list mirrors rust-toolchain.toml's, rust-analyzer + # included, even though nothing in this job runs it. rustup reconciles + # that file against the installed toolchain on the first cargo call in + # the work tree and fetches whatever is missing — so leaving it out does + # not save the download, it only moves it into the middle of a build + # step where it is nobody's line item. Naming it here keeps every fetch + # inside the step whose name says it is installing things. - name: Install Rust 1.92.0 run: | set -e curl -fsSL https://sh.rustup.rs | sh -s -- \ -y --no-modify-path --profile minimal \ - --default-toolchain 1.92.0 --component rustfmt,clippy + --default-toolchain 1.92.0 --component rustfmt,clippy,rust-analyzer echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" # Free space before and after the expensive steps, so a repeat of the @@ -370,11 +378,17 @@ jobs: # `cargo tree` resolves the dependency graph, so it needs the registry # index but no system libraries — this job builds nothing. + # + # rust-analyzer is named for the reason given in the desktop job: rustup + # installs rust-toolchain.toml's components on the first cargo call + # whether or not this step asks for them, and an unasked-for download is + # the one nobody can find in the log. - name: Install Rust 1.92.0 run: | set -e curl -fsSL https://sh.rustup.rs | sh -s -- \ - -y --no-modify-path --profile minimal --default-toolchain 1.92.0 + -y --no-modify-path --profile minimal --default-toolchain 1.92.0 \ + --component rust-analyzer echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" # ARCH §6.5a: no core/ crate may depend on the UI toolkit. One stray diff --git a/.gitea/workflows/traceability-check.yml b/.gitea/workflows/traceability-check.yml index 8b37b2d..68e7ba0 100644 --- a/.gitea/workflows/traceability-check.yml +++ b/.gitea/workflows/traceability-check.yml @@ -44,12 +44,17 @@ jobs: key: traces-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }} # Source-comment and markdown parsing only, so the minimal profile is - # enough — no system libraries and no components beyond cargo itself. + # enough — no system libraries and nothing this job itself needs beyond + # cargo. rust-analyzer is here anyway because rust-toolchain.toml lists + # it: rustup installs that file's components on the first cargo call in + # the work tree regardless, and a download named in the install step + # beats the same download appearing unannounced inside the gate. - name: Install Rust 1.92.0 run: | set -e curl -fsSL https://sh.rustup.rs | sh -s -- \ - -y --no-modify-path --profile minimal --default-toolchain 1.92.0 + -y --no-modify-path --profile minimal --default-toolchain 1.92.0 \ + --component rust-analyzer echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" # The gate's own arithmetic is the thing being trusted, so its tests run diff --git a/docker/android/Dockerfile b/docker/android/Dockerfile index ca1cd62..6f6c6d3 100644 --- a/docker/android/Dockerfile +++ b/docker/android/Dockerfile @@ -118,6 +118,14 @@ ENV ANDROID_NDK_HOME=${ANDROID_HOME}/ndk/${NDK_VERSION} \ # # All four ABIs. arm64-v8a covers essentially every current device; the others # exist so an ABI-specific build break is caught here rather than at release. +# +# The component list must be a superset of rust-toolchain.toml's. rustup +# reconciles that file against the installed toolchain on the first cargo +# invocation in the work tree, and silently downloads whatever is missing — +# inside the CI job, after this image has already been pulled. Anything the +# repo asks for therefore belongs here, or the image is not the whole +# environment it claims to be. rust-analyzer is in that list for the editor's +# sake; here it costs a layer and buys a job that fetches nothing. # --------------------------------------------------------------------------- RUN curl -fsSL https://sh.rustup.rs | sh -s -- \ -y --no-modify-path --profile minimal --default-toolchain ${RUST_VERSION} \ @@ -126,7 +134,7 @@ RUN curl -fsSL https://sh.rustup.rs | sh -s -- \ armv7-linux-androideabi \ x86_64-linux-android \ i686-linux-android \ - && rustup component add rustfmt clippy \ + && rustup component add rustfmt clippy rust-analyzer \ && cargo install cargo-ndk --locked \ && chmod -R a+rwX ${CARGO_HOME} ${RUSTUP_HOME} diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 82aa8c7..2c79a60 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -17,7 +17,20 @@ # sufficient one. # # rustup reads this automatically and will fetch the toolchain on first use. +# +# `rust-analyzer` is in the component list for the editor's sake, not the +# build's. VS Code's rust-analyzer extension ships a server newer than 1.92.0 +# supports; without a component here it prompts, on every window, to add one. +# Listing it makes rustup supply the server that matches the pin, which is the +# same thing the pin buys everywhere else. +# +# Adding anything here has a cost outside the editor: rustup reconciles this +# list against the installed toolchain on the first cargo call in the work +# tree and downloads what is missing, inside whatever job is running. So every +# environment that builds this repo already carries it — baked into +# docker/android's image, and named in the install step of each CI job that +# rolls its own toolchain. Keep those in step with this line. [toolchain] channel = "1.92.0" -components = ["rustfmt", "clippy"] +components = ["rustfmt", "clippy", "rust-analyzer"]