mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-30 07:37:36 +00:00
The build legs, the unit-test jobs and both Linux architectures all wrote the cache key `<os>-cargo-<lock>`, so whichever job saved first owned the entry and the others recompiled every dependency on an exact hit: a Windows unit-test run compiled 285 crates against the release build's entry. The repository's cache had also grown past its 10 GB limit, with every branch saving its own copies. Each job that builds Rust now uses Swatinem/rust-cache with a key per job, OS and architecture, a hash of the installed toolchains and Cargo environment, and a hash of Cargo.lock and the manifests with the workspace versions blanked, so a version bump keeps the key. It caches the registry and the dependency artifacts only, and only a push to master saves; every other ref restores master's entry. rust-cache hashes every installed toolchain, and GitHub's runner images ship their own stable Rust that changes with each image release, so each cached job first removes every toolchain but the one rust-toolchain.toml pins, and fails unless only that one is left.
66 lines
2.5 KiB
Bash
Executable File
66 lines
2.5 KiB
Bash
Executable File
#!/bin/bash
|
|
# ── Remove every Rust toolchain but the pinned one ──────────────────────────
|
|
# rust-cache puts a hash of every installed toolchain's `rustc -vV` in its cache
|
|
# key. GitHub's runner images ship their own stable Rust, which moves with each
|
|
# image release, so while it stays installed the key changes whenever GitHub
|
|
# rolls a new image, and during a rollout runs alternate between two keys and
|
|
# miss each other's entries (rustc 1.99.0 on image 20261012, 1.99.1 on
|
|
# 20261018). Removing it leaves only rust-toolchain.toml's channel in the hash.
|
|
#
|
|
# The channel is read from a line exactly `channel = "<version>"`; any other
|
|
# spelling fails closed with "no channel".
|
|
#
|
|
# Called from .github/workflows/ci.yml between the toolchain install and the
|
|
# cache step of every job that uses rust-cache.
|
|
#
|
|
# Exit 0 = `rustup toolchain list --quiet`, the list rust-cache hashes, names
|
|
# only the pinned channel. Non-zero = the pin could not be read, the pinned
|
|
# toolchain is missing, or another toolchain is still installed afterwards.
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
set -euo pipefail
|
|
|
|
pinned=$(sed -n 's/^channel = "\(.*\)"$/\1/p' rust-toolchain.toml)
|
|
if [[ -z $pinned ]]; then
|
|
echo "keep-pinned-toolchain: no channel in rust-toolchain.toml" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Names only, without the Windows carriage return; rustup exits 0 when asked
|
|
# to uninstall a name it does not have, so a mangled name would otherwise
|
|
# leave its toolchain in place unnoticed.
|
|
toolchains() {
|
|
local list
|
|
list=$(rustup toolchain list --quiet)
|
|
printf '%s\n' "${list//$'\r'/}"
|
|
}
|
|
|
|
list=$(toolchains)
|
|
kept=""
|
|
while read -r name; do
|
|
if [[ $name == "$pinned"-* ]]; then
|
|
kept=${kept:-$name}
|
|
fi
|
|
done <<<"$list"
|
|
if [[ -z $kept ]]; then
|
|
echo "keep-pinned-toolchain: toolchain $pinned is not installed" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# The image's stable is usually the default; repoint it first so nothing is
|
|
# left defaulting to a removed toolchain.
|
|
rustup default "$kept"
|
|
while read -r name; do
|
|
if [[ -n $name && $name != "$pinned"-* ]]; then
|
|
rustup toolchain uninstall "$name"
|
|
fi
|
|
done <<<"$list"
|
|
|
|
left=$(toolchains)
|
|
while read -r name; do
|
|
if [[ $name != "$pinned"-* ]]; then
|
|
echo "keep-pinned-toolchain: still installed: '$name'" >&2
|
|
exit 1
|
|
fi
|
|
done <<<"$left"
|
|
printf '%s\n' "$left"
|