Files
Genarrative/scripts/ci-rust-cache.sh
T
lhk229 292e42cf5e
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (push) Successful in 1m22s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m51s
Project CI / Backend tests (push) Successful in 5m35s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 7m8s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 8m11s
Project CI / Native shell tests (push) Successful in 7m6s
Project CI / Frontend tests (push) Successful in 3m30s
Project CI / Repository checks (push) Successful in 3m28s
Project CI / AI game creator shell web tests (push) Successful in 3m7s
为全部 Rust 测试组启用隔离编译缓存
扩展缓存消费到 AGC 双 lane、crates、smoke、后端及桌面壳测试
补齐各组实际编译目标和工作目录的可信快照预热
保留 SpacetimeDB 独立编译边界并排除发布构建缓存
根据完整快照体积将对象缓存上限调整为 4 GiB
更新工作流契约测试、运维文档及项目共享记忆
2026-09-22 05:52:16 +00:00

87 lines
4.0 KiB
Bash

#!/usr/bin/env bash
# 仅消费镜像内的可信快照;所有写入留在当前容器的可写层。
set -euo pipefail
cache_root="${GENARRATIVE_CI_RUST_CACHE_ROOT:-/opt/genarrative-ci/rust-cache}"
cache_binary="${cache_root}/sccache"
state="${GENARRATIVE_CI_RUST_CACHE_STATE:-}"
configure_local_cache() {
# 不继承开发机/其它流水线的 OSS、S3、GHA 或 daemon 配置。
local variable
for variable in ${!SCCACHE_@}; do unset "${variable}"; done
export SCCACHE_CONF="${state}/config"
export SCCACHE_DIR="${cache_root}/objects"
export SCCACHE_CACHE_SIZE=4G
export SCCACHE_SERVER_UDS="${state}/server.sock"
# 单个不可缓存的链接/测试阶段可能超过一分钟;保持统计直到 report 显式停止。
export SCCACHE_IDLE_TIMEOUT=0
export SCCACHE_IGNORE_SERVER_IO_ERROR=1
}
case "${1:-}" in
prepare)
: "${GITHUB_ENV:?GITHUB_ENV is required}"
printf 'RUSTC_WRAPPER=\nCARGO_BUILD_RUSTC_WRAPPER=\nGENARRATIVE_CI_RUST_CACHE_STATE=\n' >> "${GITHUB_ENV}"
fallback() { printf '[rust-cache] mode=direct reason=%s\n' "$1"; exit 0; }
[[ -x "${cache_binary}" && -d "${cache_root}/objects" && -f "${cache_root}/rustc.txt" && -f "${cache_root}/source-commit.txt" && -f "${cache_root}/workspace.txt" ]] \
|| fallback snapshot-unavailable
if ! rustc -vV | cmp -s - "${cache_root}/rustc.txt"; then
fallback toolchain-mismatch
fi
if [[ "$(pwd -P)" != "$(cat "${cache_root}/workspace.txt")" ]]; then
fallback workspace-mismatch
fi
# 使用短 Unix socket 路径,避免共享固定端口或超出 sockaddr_un 长度。
state="$(mktemp -d /tmp/ci-rust-cache.XXXXXX)"
printf 'server_startup_timeout_ms = 5000\n' > "${state}/config"
configure_local_cache
# 探测必须暴露 daemon 故障;只有正式编译允许 sccache 的 IO 回退。
unset SCCACHE_IGNORE_SERVER_IO_ERROR
if ! timeout --kill-after=2 15 "${cache_binary}" "$(command -v rustc)" -vV > "${state}/probe.log" 2>&1; then
timeout --kill-after=2 5 "${cache_binary}" --stop-server >/dev/null 2>&1 || true
rm -rf -- "${state}"
fallback wrapper-probe-failed
fi
script_path="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)/$(basename "${BASH_SOURCE[0]}")"
# wrapper 路径也参与 Rust cache key;固定容器内路径,隔离由 job 容器保证。
wrapper_path="${cache_root}/rustc-wrapper"
printf '#!/usr/bin/env bash\nexec bash %q "$@"\n' "${script_path}" > "${wrapper_path}"
chmod 700 "${wrapper_path}"
{
printf 'GENARRATIVE_CI_RUST_CACHE_ROOT=%s\n' "${cache_root}"
printf 'GENARRATIVE_CI_RUST_CACHE_STATE=%s\n' "${state}"
printf 'RUSTC_WRAPPER=%s\nCARGO_BUILD_RUSTC_WRAPPER=%s\n' "${wrapper_path}" "${wrapper_path}"
} >> "${GITHUB_ENV}"
printf '[rust-cache] mode=sccache snapshot=%s\n' "$(cat "${cache_root}/source-commit.txt")"
;;
report)
if [[ -n "${state}" && -d "${state}" ]]; then
configure_local_cache
timeout --kill-after=2 5 "${cache_binary}" --show-stats || true
timeout --kill-after=2 5 "${cache_binary}" --stop-server >/dev/null 2>&1 || true
rm -rf -- "${state}"
else
printf '[rust-cache] mode=direct\n'
fi
;;
*)
# Cargo wrapper 协议:第一个参数是真实 rustc。失去缓存状态时仍执行原编译。
if [[ -z "${state}" || ! -f "${state}/config" || -f "${state}/disabled" || ! -x "${cache_binary}" ]]; then
exec "$@"
fi
configure_local_cache
status=0
"${cache_binary}" "$@" || status=$?
if [[ "${status}" == 2 ]]; then
# 固定 sccache 版本的自身错误码为 2;实际 rustc 失败通常为 1/101。
# 只重试这次编译,不重跑 Cargo 或测试,真实编译错误仍按 rustc 状态返回。
echo '[rust-cache] cache infrastructure failed; compiling directly' >&2
# 后续 crate 直接编译,避免坏 daemon 让每个 crate 都支付一次启动超时。
: > "${state}/disabled"
exec "$@"
fi
exit "${status}"
;;
esac