Something went wrong. Try again.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113#!/usr/bin/env sh#MISE description="Restore or save the Rust build cache (cargo home + target) in R2, keyed on OS + rustc + Cargo.lock"
set -e
shared="${POD_RUST_CACHE_SHARED_KEY:-}"[ -n "${shared}" ] || shared="default"
os="$(printf '%s' "${RUNNER_OS:-$(uname -s)}" | tr '[:upper:]' '[:lower:]')"rustc_id="$(rustc -V | git hash-object --stdin | cut -c1-12)"lock_id="$(git hash-object Cargo.lock | cut -c1-16)"
dir="rust-cache/${shared}"name_prefix="${os}-${rustc_id}-"key_base="${name_prefix}${lock_id}"
cargo_home="${CARGO_HOME:-${HOME}/.cargo}"# git-bash on the Windows runner hands back a Windows-form path (C:\Users\...\.cargo)# that tar's -C and mkdir -p cannot open; normalize it to POSIX. cygpath is absent on# Linux/macOS, where the path is already POSIX, so this is a no-op there.if command -v cygpath >/dev/null 2>&1; then cargo_home="$(cygpath -u "${cargo_home}")"fi
work="$(mktemp -d)"trap 'rm -rf "${work}"' EXIT
# The cargo home (registry + git) and target/ have different roots, so each is a# separate object tarred relative to its own base — no absolute paths, portable# across the Linux, macOS, and Windows (git-bash) runners.pick_newest() { part="$1" mise run ci:r2 list "${dir}/" 2>/dev/null | awk -F';' -v pfx="${name_prefix}" -v sfx=".${part}.tar.gz" \ 'index($2, pfx) == 1 && substr($2, length($2) - length(sfx) + 1) == sfx' | sort -r | head -1 | cut -d';' -f2}
restore_part() { part="$1" base="$2" exact="${dir}/${key_base}.${part}.tar.gz" tarball="${work}/${part}.tar.gz"
if mise run ci:r2 get "${exact}" "${tarball}"; then echo "rust-cache: restored ${part} (exact Cargo.lock ${lock_id})" else name="$(pick_newest "${part}")" if [ -z "${name}" ]; then echo "rust-cache: no ${part} cache — cold" return 0 fi if ! mise run ci:r2 get "${dir}/${name}" "${tarball}"; then echo "rust-cache: ${part} fallback fetch failed — cold" return 0 fi echo "rust-cache: restored ${part} via fallback ${name}" fi
mkdir -p "${base}" tar -xzf "${tarball}" -C "${base}" || echo "rust-cache: ${part} extract failed — continuing cold" rm -f "${tarball}"}
save_part() { part="$1" base="$2" shift 2 members="" for m in "$@"; do if [ -d "${base}/${m}" ]; then members="${members} ${m}" fi done if [ -z "${members}" ]; then echo "rust-cache: nothing to save for ${part}" return 0 fi
excludes="" if [ "${part}" = "target" ]; then for pat in '*.dmg' '*.app' '*.app.tar.gz' '*.app.tar.gz.sig' '*-setup.exe' \ '*.msi' '*.exe.sig' '*.AppImage' '*.AppImage.sig' '*.deb' '*.pkg.tar.zst' \ '*.tar.gz' '*.dSYM'; do excludes="${excludes} --exclude=${pat}" done fi
tarball="${work}/${part}.tar.gz" # shellcheck disable=SC2086 tar -czf "${tarball}" ${excludes} -C "${base}" ${members} mise run ci:r2 put "${tarball}" "${dir}/${key_base}.${part}.tar.gz" echo "rust-cache: saved ${part} (${members# })" rm -f "${tarball}"}
case "${1:-}" inrestore) echo "rust-cache: key ${dir}/${key_base}" restore_part cargo "${cargo_home}" restore_part target "$(pwd)" ;;save) echo "rust-cache: key ${dir}/${key_base}" save_part cargo "${cargo_home}" registry git save_part target "$(pwd)" target ;;*) echo "usage: rust-cache <restore|save>" >&2 exit 2 ;;esac