chore: import upstream snapshot with attribution
This commit is contained in:
Executable
+277
@@ -0,0 +1,277 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
MIRROR_BASE_URL="https://build.rerun.io/mirror/mozilla/sccache"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Install and configure sccache for CI.
|
||||
|
||||
Usage: setup_sccache.sh --version VERSION [--backend auto|s3|gcs] [--gcs-bucket BUCKET] [--gcs-read-only [true|false]]
|
||||
EOF
|
||||
}
|
||||
|
||||
version=""
|
||||
backend="auto"
|
||||
gcs_bucket="rerun-sccache"
|
||||
gcs_read_only="false"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--version)
|
||||
version="${2:?--version requires a value}"
|
||||
shift 2
|
||||
;;
|
||||
--backend)
|
||||
backend="${2:?--backend requires a value}"
|
||||
shift 2
|
||||
;;
|
||||
--gcs-bucket)
|
||||
gcs_bucket="${2:?--gcs-bucket requires a value}"
|
||||
shift 2
|
||||
;;
|
||||
--gcs-read-only)
|
||||
if [[ "${2:-}" == "true" || "${2:-}" == "false" ]]; then
|
||||
gcs_read_only="$2"
|
||||
shift 2
|
||||
else
|
||||
gcs_read_only="true"
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown argument: $1" >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z "$version" ]]; then
|
||||
echo "--version is required" >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
append_line() {
|
||||
local path="$1"
|
||||
local line="$2"
|
||||
printf '%s\n' "$line" >> "$path"
|
||||
}
|
||||
|
||||
export_env() {
|
||||
local name="$1"
|
||||
local value="$2"
|
||||
export "$name=$value"
|
||||
append_line "${GITHUB_ENV:?GITHUB_ENV is required}" "$name=$value"
|
||||
}
|
||||
|
||||
runner_arch() {
|
||||
local raw="${RUNNER_ARCH:-$(uname -m)}"
|
||||
case "$raw" in
|
||||
X64|x64|x86_64|AMD64|amd64) echo "x86_64" ;;
|
||||
ARM64|arm64|aarch64) echo "aarch64" ;;
|
||||
ARM|arm|armv7|armv7l) echo "armv7" ;;
|
||||
*) echo "Unsupported architecture: $raw" >&2; exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
runner_platform() {
|
||||
local raw="${RUNNER_OS:-$(uname -s)}"
|
||||
case "$raw" in
|
||||
Linux|linux) echo "unknown-linux-musl tar.gz sccache" ;;
|
||||
macOS|Darwin|darwin) echo "apple-darwin tar.gz sccache" ;;
|
||||
Windows|windows|MINGW*|MSYS*|CYGWIN*) echo "pc-windows-msvc zip sccache.exe" ;;
|
||||
*) echo "Unsupported OS: $raw" >&2; exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
download() {
|
||||
local url="$1"
|
||||
local destination="$2"
|
||||
local curl_args=(--fail --location --retry 4 --connect-timeout 30 --max-time 120)
|
||||
if curl --help all 2>/dev/null | grep -q -- '--retry-all-errors'; then
|
||||
curl_args+=(--retry-all-errors)
|
||||
fi
|
||||
echo "Downloading $url" >&2
|
||||
curl "${curl_args[@]}" --user-agent "rerun-setup-sccache" --output "$destination" "$url"
|
||||
}
|
||||
|
||||
sha1_file() {
|
||||
local path="$1"
|
||||
if command -v sha1sum >/dev/null 2>&1; then
|
||||
sha1sum "$path" | awk '{print $1}'
|
||||
elif command -v shasum >/dev/null 2>&1; then
|
||||
shasum -a 1 "$path" | awk '{print $1}'
|
||||
elif command -v openssl >/dev/null 2>&1; then
|
||||
openssl sha1 "$path" | awk '{print $NF}'
|
||||
else
|
||||
echo "No SHA1 tool found" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
verify_sha1() {
|
||||
local archive="$1"
|
||||
local sha1_path="$2"
|
||||
local expected actual
|
||||
expected="$(awk '{print $1}' "$sha1_path")"
|
||||
# shellcheck disable=SC2218 # False positive: sha1_file is defined before verify_sha1 is called.
|
||||
actual="$(sha1_file "$archive")"
|
||||
actual="$(printf '%s' "$actual" | tr '[:upper:]' '[:lower:]')"
|
||||
expected="$(printf '%s' "$expected" | tr '[:upper:]' '[:lower:]')"
|
||||
# GNU checksum tools prefix hashes with `\` when paths contain backslashes.
|
||||
# See also: https://unix.stackexchange.com/a/424629
|
||||
actual="${actual#\\}"
|
||||
expected="${expected#\\}"
|
||||
if [[ "$actual" != "$expected" ]]; then
|
||||
echo "SHA1 mismatch for $(basename "$archive"): expected $expected, got $actual" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
extract_archive() {
|
||||
local archive="$1"
|
||||
local destination="$2"
|
||||
local extension="$3"
|
||||
if [[ "$extension" == "zip" ]]; then
|
||||
if command -v unzip >/dev/null 2>&1; then
|
||||
unzip -q "$archive" -d "$destination"
|
||||
elif command -v powershell.exe >/dev/null 2>&1; then
|
||||
powershell.exe -NoProfile -Command "Expand-Archive -LiteralPath '$archive' -DestinationPath '$destination' -Force"
|
||||
else
|
||||
echo "No zip extraction tool found" >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
tar -xzf "$archive" -C "$destination"
|
||||
fi
|
||||
}
|
||||
|
||||
resolve_backend() {
|
||||
if [[ "$backend" != "auto" ]]; then
|
||||
echo "$backend"
|
||||
elif [[ "${RUNNER_OS:-}" == "Linux" && -n "${RUNS_ON_S3_BUCKET_CACHE:-}" ]]; then
|
||||
echo "s3"
|
||||
else
|
||||
echo "gcs"
|
||||
fi
|
||||
}
|
||||
|
||||
write_config() {
|
||||
local path="$1"
|
||||
local resolved_backend="$2"
|
||||
local rw_mode="READ_WRITE"
|
||||
|
||||
if [[ "$gcs_read_only" == "true" ]]; then
|
||||
rw_mode="READ_ONLY"
|
||||
fi
|
||||
|
||||
{
|
||||
echo "server_startup_timeout_ms = 60000"
|
||||
if [[ "$resolved_backend" == "gcs" ]]; then
|
||||
cat <<EOF
|
||||
|
||||
[cache.gcs]
|
||||
bucket = "$gcs_bucket"
|
||||
key_prefix = "_sccache"
|
||||
rw_mode = "$rw_mode"
|
||||
EOF
|
||||
fi
|
||||
} > "$path"
|
||||
}
|
||||
|
||||
configure_backend() {
|
||||
local resolved_backend="$1"
|
||||
case "$resolved_backend" in
|
||||
s3)
|
||||
if [[ -z "${RUNS_ON_S3_BUCKET_CACHE:-}" ]]; then
|
||||
echo "RUNS_ON_S3_BUCKET_CACHE is required for s3 backend" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z "${RUNS_ON_AWS_REGION:-}" ]]; then
|
||||
echo "RUNS_ON_AWS_REGION is required for s3 backend" >&2
|
||||
exit 1
|
||||
fi
|
||||
export_env "SCCACHE_BUCKET" "$RUNS_ON_S3_BUCKET_CACHE"
|
||||
export_env "SCCACHE_REGION" "$RUNS_ON_AWS_REGION"
|
||||
export_env "SCCACHE_S3_KEY_PREFIX" "cache/sccache"
|
||||
;;
|
||||
gcs)
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported backend: $resolved_backend" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
write_config "${SCCACHE_CONF:?SCCACHE_CONF is required}" "$resolved_backend"
|
||||
}
|
||||
|
||||
start_server() {
|
||||
local sccache_bin="$1"
|
||||
for attempt in 1 2 3; do
|
||||
echo "Starting sccache server (attempt $attempt/3)…"
|
||||
if "$sccache_bin" --start-server; then
|
||||
"$sccache_bin" --show-stats
|
||||
return
|
||||
fi
|
||||
if [[ "$attempt" != "3" ]]; then
|
||||
sleep $((attempt * 5))
|
||||
fi
|
||||
done
|
||||
echo "sccache --start-server failed after 3 attempts" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
install_sccache() {
|
||||
local arch target_platform extension exe filename install_root archive sha1_path extract_dir bin_dir sccache_bin base_url
|
||||
# shellcheck disable=SC2218 # False positive: runner_arch is defined before install_sccache is called.
|
||||
arch="$(runner_arch)"
|
||||
read -r target_platform extension exe <<< "$(runner_platform)"
|
||||
filename="sccache-${version}-${arch}-${target_platform}.${extension}"
|
||||
install_root="${RUNNER_TEMP:?RUNNER_TEMP is required}/sccache-${version}-${arch}-${target_platform}"
|
||||
archive="$install_root/$filename"
|
||||
sha1_path="$archive.sha1"
|
||||
extract_dir="$install_root/extract"
|
||||
bin_dir="$extract_dir/sccache-${version}-${arch}-${target_platform}"
|
||||
sccache_bin="$bin_dir/$exe"
|
||||
|
||||
mkdir -p "$install_root" "$extract_dir"
|
||||
base_url="$MIRROR_BASE_URL/$version"
|
||||
download "$base_url/$filename" "$archive"
|
||||
download "$base_url/$filename.sha1" "$sha1_path"
|
||||
verify_sha1 "$archive" "$sha1_path"
|
||||
extract_archive "$archive" "$extract_dir" "$extension"
|
||||
|
||||
if [[ ! -f "$sccache_bin" ]]; then
|
||||
echo "Missing extracted sccache binary at $sccache_bin" >&2
|
||||
echo "Extracted files:" >&2
|
||||
find "$extract_dir" -print >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
append_line "${GITHUB_PATH:?GITHUB_PATH is required}" "$bin_dir"
|
||||
echo "$sccache_bin"
|
||||
}
|
||||
|
||||
case "$backend" in
|
||||
auto|s3|gcs) ;;
|
||||
*) echo "Unsupported backend: $backend" >&2; exit 2 ;;
|
||||
esac
|
||||
|
||||
# shellcheck disable=SC2218 # False positive: resolve_backend is defined above.
|
||||
resolved_backend="$(resolve_backend)"
|
||||
sccache_bin="$(install_sccache)"
|
||||
|
||||
export_env "SCCACHE_PATH" "$sccache_bin"
|
||||
export_env "SCCACHE_GHA_ENABLED" "false"
|
||||
export_env "RUSTC_WRAPPER" "sccache"
|
||||
export_env "CARGO_INCREMENTAL" "0"
|
||||
export_env "SCCACHE_CONF" "${RUNNER_TEMP:?RUNNER_TEMP is required}/sccache-config.toml"
|
||||
configure_backend "$resolved_backend"
|
||||
start_server "$sccache_bin"
|
||||
Reference in New Issue
Block a user