Skip to content
109 linesCodeBlameRaw
1#!/usr/bin/env bash
2# sccache for a workflow's Rust builds. Every rustc call that makes a
3# library is looked up by what it compiles (sources, flags, toolchain,
4# dependencies) in the repository's Actions cache, the one `actions/cache`
5# uses, through sccache's GitHub Actions backend. A checkout gives every
6# source file a new mtime, so Cargo calls rustc again for the workspace's
7# own crates however much of `target/` was restored; with sccache, the
8# crates whose inputs did not change come back from the cache instead of
9# being compiled. Binaries, cdylibs (a Worker's own crate), proc macros and
10# test harnesses are linked, and sccache compiles those as before.
11#
12# bash scripts/sccache.sh install # a step before the first cargo
13# bash scripts/sccache.sh stats # the last step, with if: always()
14#
15# install downloads the pinned release and checks its sha256, starts the
16# server (which reads and writes a check entry in the cache), and only then
17# sets RUSTC_WRAPPER for the steps after it. If anything there fails, the
18# job builds as it did without sccache, and the step says why.
19# stats prints the server's hits and misses, and adds them to the job's
20# summary.
21#
22# See docs/DEPLOYING.md ("Build speed") and the Actions guide's
23# "Caching Rust builds".
24set -euo pipefail
25
26VERSION=0.18.0
27TARGET=x86_64-unknown-linux-musl
28# sccache-v0.18.0-x86_64-unknown-linux-musl.tar.gz, from the release's
29# .sha256 file.
30SHA256=45f1447fbe231e3037bde351ef70677dd212216c8d62ae7ca409fecc4d6acc89
31
32BIN="$HOME/.cargo/bin"
33SCCACHE="$BIN/sccache"
34
35# What sccache and Cargo read, here and in the steps after this one.
36export SCCACHE_GHA_ENABLED=true
37# One server for the whole job: its statistics are the job's.
38export SCCACHE_IDLE_TIMEOUT=0
39# If the server goes away mid-build, rustc runs without it.
40export SCCACHE_IGNORE_SERVER_IO_ERROR=1
41# sccache cannot cache incremental builds; a fresh checkout gains nothing
42# from them anyway.
43export CARGO_INCREMENTAL=0
44
45warn() { echo "::warning title=sccache::$1, so this job builds without it"; }
46
47fetch() {
48 local name="sccache-v${VERSION}-${TARGET}"
49 local dir="${RUNNER_TEMP:-/tmp}/sccache-${VERSION}"
50 if [ -x "$SCCACHE" ] && [ "$("$SCCACHE" --version 2>/dev/null | awk '{print $2}')" = "$VERSION" ]; then
51 return 0
52 fi
53 mkdir -p "$dir" "$BIN"
54 curl -fsSL --retry 3 -o "$dir/$name.tar.gz" "https://github.com/mozilla/sccache/releases/download/v${VERSION}/${name}.tar.gz" || return 1
55 echo "${SHA256} $dir/$name.tar.gz" | sha256sum -c --quiet - || return 1
56 tar -xzf "$dir/$name.tar.gz" -C "$dir" || return 1
57 install -m 0755 "$dir/$name/sccache" "$SCCACHE"
58}
59
60install_sccache() {
61 if [ -z "${ACTIONS_RUNTIME_TOKEN:-}" ] || [ -z "${ACTIONS_CACHE_URL:-}${ACTIONS_RESULTS_URL:-}" ]; then
62 warn "The job has no Actions cache to use (ACTIONS_RUNTIME_TOKEN, ACTIONS_CACHE_URL)"
63 return 0
64 fi
65 if ! fetch; then
66 warn "sccache ${VERSION} could not be downloaded or did not match its checksum"
67 return 0
68 fi
69 if ! "$SCCACHE" --start-server; then
70 warn "sccache's server did not start (it could not read the cache)"
71 return 0
72 fi
73 {
74 echo "RUSTC_WRAPPER=$SCCACHE"
75 echo "SCCACHE_GHA_ENABLED=$SCCACHE_GHA_ENABLED"
76 echo "SCCACHE_IDLE_TIMEOUT=$SCCACHE_IDLE_TIMEOUT"
77 echo "SCCACHE_IGNORE_SERVER_IO_ERROR=$SCCACHE_IGNORE_SERVER_IO_ERROR"
78 echo "CARGO_INCREMENTAL=$CARGO_INCREMENTAL"
79 } >> "$GITHUB_ENV"
80 echo "sccache ${VERSION}: rustc goes through it from here on, cached in this repository's Actions cache."
81}
82
83stats() {
84 if [ -z "${RUSTC_WRAPPER:-}" ] || [ ! -x "$SCCACHE" ]; then
85 echo "sccache was not used in this job."
86 return 0
87 fi
88 local out
89 out="$("$SCCACHE" --show-stats 2>&1)" || true
90 echo "$out"
91 if [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then
92 {
93 echo "### sccache"
94 echo
95 echo '```'
96 echo "$out"
97 echo '```'
98 } >> "$GITHUB_STEP_SUMMARY"
99 fi
100}
101
102case "${1:-}" in
103 install) install_sccache ;;
104 stats) stats ;;
105 *)
106 echo "usage: bash scripts/sccache.sh install|stats" >&2
107 exit 2
108 ;;
109esac