setup-sccache

  1#!/usr/bin/env bash
  2
  3set -euo pipefail
  4
  5SCCACHE_VERSION="v0.10.0"
  6# Use absolute path to avoid issues with working directory changes between steps
  7SCCACHE_DIR="$(pwd)/target/sccache"
  8
  9install_sccache() {
 10    mkdir -p "$SCCACHE_DIR"
 11
 12    if [[ -x "${SCCACHE_DIR}/sccache" ]] && "${SCCACHE_DIR}/sccache" --version &>/dev/null; then
 13        echo "sccache already cached: $("${SCCACHE_DIR}/sccache" --version)"
 14    else
 15        echo "Installing sccache ${SCCACHE_VERSION} from GitHub releases..."
 16
 17        local os arch archive basename
 18        os="$(uname -s)"
 19        arch="$(uname -m)"
 20
 21        case "${os}-${arch}" in
 22            Darwin-arm64)
 23                archive="sccache-${SCCACHE_VERSION}-aarch64-apple-darwin.tar.gz"
 24                ;;
 25            Darwin-x86_64)
 26                archive="sccache-${SCCACHE_VERSION}-x86_64-apple-darwin.tar.gz"
 27                ;;
 28            Linux-x86_64)
 29                archive="sccache-${SCCACHE_VERSION}-x86_64-unknown-linux-musl.tar.gz"
 30                ;;
 31            Linux-aarch64)
 32                archive="sccache-${SCCACHE_VERSION}-aarch64-unknown-linux-musl.tar.gz"
 33                ;;
 34            *)
 35                echo "Unsupported platform: ${os}-${arch}"
 36                exit 1
 37                ;;
 38        esac
 39
 40        basename="${archive%.tar.gz}"
 41        curl -fsSL "https://github.com/mozilla/sccache/releases/download/${SCCACHE_VERSION}/${archive}" | tar xz
 42        mv "${basename}/sccache" "${SCCACHE_DIR}/"
 43        rm -rf "${basename}"
 44        echo "Installed sccache: $("${SCCACHE_DIR}/sccache" --version)"
 45    fi
 46
 47    # Verify the binary works before adding to path
 48    if ! "${SCCACHE_DIR}/sccache" --version &>/dev/null; then
 49        echo "ERROR: sccache binary at ${SCCACHE_DIR}/sccache is not executable or corrupted"
 50        rm -f "${SCCACHE_DIR}/sccache"
 51        exit 1
 52    fi
 53
 54    if [[ -n "${GITHUB_PATH:-}" ]]; then
 55        echo "${SCCACHE_DIR}" >> "$GITHUB_PATH"
 56    fi
 57    export PATH="${SCCACHE_DIR}:${PATH}"
 58}
 59
 60configure_sccache() {
 61    if [[ -z "${R2_ACCOUNT_ID:-}" ]]; then
 62        echo "R2_ACCOUNT_ID not set, skipping sccache configuration"
 63        return
 64    fi
 65
 66    echo "Configuring sccache with Cloudflare R2..."
 67
 68    local bucket="${SCCACHE_BUCKET:-sccache-zed}"
 69    local key_prefix="${SCCACHE_KEY_PREFIX:-sccache/}"
 70    local base_dir="${GITHUB_WORKSPACE:-$(pwd)}"
 71
 72    # Use the absolute path to sccache binary for RUSTC_WRAPPER to avoid
 73    # any PATH race conditions between GITHUB_PATH and GITHUB_ENV
 74    local sccache_bin="${SCCACHE_DIR}/sccache"
 75
 76    # Set in current process
 77    export SCCACHE_ENDPOINT="https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com"
 78    export SCCACHE_BUCKET="${bucket}"
 79    export SCCACHE_REGION="auto"
 80    export SCCACHE_S3_KEY_PREFIX="${key_prefix}"
 81    export SCCACHE_BASEDIR="${base_dir}"
 82    export AWS_ACCESS_KEY_ID="${R2_ACCESS_KEY_ID}"
 83    export AWS_SECRET_ACCESS_KEY="${R2_SECRET_ACCESS_KEY}"
 84    export RUSTC_WRAPPER="${sccache_bin}"
 85
 86    # Also write to GITHUB_ENV for subsequent steps
 87    if [[ -n "${GITHUB_ENV:-}" ]]; then
 88        {
 89            echo "SCCACHE_ENDPOINT=${SCCACHE_ENDPOINT}"
 90            echo "SCCACHE_BUCKET=${SCCACHE_BUCKET}"
 91            echo "SCCACHE_REGION=${SCCACHE_REGION}"
 92            echo "SCCACHE_S3_KEY_PREFIX=${SCCACHE_S3_KEY_PREFIX}"
 93            echo "SCCACHE_BASEDIR=${SCCACHE_BASEDIR}"
 94            echo "AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}"
 95            echo "AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}"
 96            echo "RUSTC_WRAPPER=${RUSTC_WRAPPER}"
 97        } >> "$GITHUB_ENV"
 98    fi
 99
100    echo "✓ sccache configured with Cloudflare R2 (bucket: ${bucket})"
101}
102
103show_config() {
104    echo "=== sccache configuration ==="
105    echo "sccache version: $(sccache --version)"
106    echo "RUSTC_WRAPPER: ${RUSTC_WRAPPER:-<not set>}"
107    echo "SCCACHE_BUCKET: ${SCCACHE_BUCKET:-<not set>}"
108    echo "SCCACHE_ENDPOINT: ${SCCACHE_ENDPOINT:-<not set>}"
109    echo "SCCACHE_REGION: ${SCCACHE_REGION:-<not set>}"
110    echo "SCCACHE_S3_KEY_PREFIX: ${SCCACHE_S3_KEY_PREFIX:-<not set>}"
111    echo "SCCACHE_BASEDIR: ${SCCACHE_BASEDIR:-<not set>}"
112    if [[ -n "${AWS_ACCESS_KEY_ID:-}" ]]; then
113        echo "AWS_ACCESS_KEY_ID: <set, length=${#AWS_ACCESS_KEY_ID}>"
114    else
115        echo "AWS_ACCESS_KEY_ID: <not set>"
116    fi
117    if [[ -n "${AWS_SECRET_ACCESS_KEY:-}" ]]; then
118        echo "AWS_SECRET_ACCESS_KEY: <set>"
119    else
120        echo "AWS_SECRET_ACCESS_KEY: <not set>"
121    fi
122    echo "=== sccache stats ==="
123    sccache --show-stats || true
124}
125
126install_sccache
127configure_sccache
128show_config