Skip to content
108 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 the Actions guide's "Caching Rust builds".
23set -euo pipefail
24
25VERSION=0.18.0
26TARGET=x86_64-unknown-linux-musl
27# sccache-v0.18.0-x86_64-unknown-linux-musl.tar.gz, from the release's
28# .sha256 file.
29SHA256=45f1447fbe231e3037bde351ef70677dd212216c8d62ae7ca409fecc4d6acc89
30
31BIN="$HOME/.cargo/bin"
32SCCACHE="$BIN/sccache"
33
34# What sccache and Cargo read, here and in the steps after this one.
35export SCCACHE_GHA_ENABLED=true
36# One server for the whole job: its statistics are the job's.
37export SCCACHE_IDLE_TIMEOUT=0
38# If the server goes away mid-build, rustc runs without it.
39export SCCACHE_IGNORE_SERVER_IO_ERROR=1
40# sccache cannot cache incremental builds; a fresh checkout gains nothing
41# from them anyway.
42export CARGO_INCREMENTAL=0
43
44warn() { echo "::warning title=sccache::$1, so this job builds without it"; }
45
46fetch() {
47 local name="sccache-v${VERSION}-${TARGET}"
48 local dir="${RUNNER_TEMP:-/tmp}/sccache-${VERSION}"
49 if [ -x "$SCCACHE" ] && [ "$("$SCCACHE" --version 2>/dev/null | awk '{print $2}')" = "$VERSION" ]; then
50 return 0
51 fi
52 mkdir -p "$dir" "$BIN"
53 curl -fsSL --retry 3 -o "$dir/$name.tar.gz" "https://github.com/mozilla/sccache/releases/download/v${VERSION}/${name}.tar.gz" || return 1
54 echo "${SHA256} $dir/$name.tar.gz" | sha256sum -c --quiet - || return 1
55 tar -xzf "$dir/$name.tar.gz" -C "$dir" || return 1
56 install -m 0755 "$dir/$name/sccache" "$SCCACHE"
57}
58
59install_sccache() {
60 if [ -z "${ACTIONS_RUNTIME_TOKEN:-}" ] || [ -z "${ACTIONS_CACHE_URL:-}${ACTIONS_RESULTS_URL:-}" ]; then
61 warn "The job has no Actions cache to use (ACTIONS_RUNTIME_TOKEN, ACTIONS_CACHE_URL)"
62 return 0
63 fi
64 if ! fetch; then
65 warn "sccache ${VERSION} could not be downloaded or did not match its checksum"
66 return 0
67 fi
68 if ! "$SCCACHE" --start-server; then
69 warn "sccache's server did not start (it could not read the cache)"
70 return 0
71 fi
72 {
73 echo "RUSTC_WRAPPER=$SCCACHE"
74 echo "SCCACHE_GHA_ENABLED=$SCCACHE_GHA_ENABLED"
75 echo "SCCACHE_IDLE_TIMEOUT=$SCCACHE_IDLE_TIMEOUT"
76 echo "SCCACHE_IGNORE_SERVER_IO_ERROR=$SCCACHE_IGNORE_SERVER_IO_ERROR"
77 echo "CARGO_INCREMENTAL=$CARGO_INCREMENTAL"
78 } >> "$GITHUB_ENV"
79 echo "sccache ${VERSION}: rustc goes through it from here on, cached in this repository's Actions cache."
80}
81
82stats() {
83 if [ -z "${RUSTC_WRAPPER:-}" ] || [ ! -x "$SCCACHE" ]; then
84 echo "sccache was not used in this job."
85 return 0
86 fi
87 local out
88 out="$("$SCCACHE" --show-stats 2>&1)" || true
89 echo "$out"
90 if [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then
91 {
92 echo "### sccache"
93 echo
94 echo '```'
95 echo "$out"
96 echo '```'
97 } >> "$GITHUB_STEP_SUMMARY"
98 fi
99}
100
101case "${1:-}" in
102 install) install_sccache ;;
103 stats) stats ;;
104 *)
105 echo "usage: bash scripts/sccache.sh install|stats" >&2
106 exit 2
107 ;;
108esac