Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

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