Files
Sebastian "Sebbie" Silbermann 988a6ab727 [ci] Authenticate Turborepo remote caching with OIDC instead of a static PAT (#97590)
CI authenticated to Vercel Remote Cache with a long-lived Personal
Access Token in the `TURBO_TOKEN` repository secret. That token never
expired, is scoped to a team member rather than the team, and is
readable by every job that inherits secrets.

Each job now mints its own short-lived, cache-only token instead, using
`vercel/setup-turborepo-remote-cache-action` against a Turborepo CLI
OIDC policy configured on the Vercel team following
https://vercel.com/docs/monorepos/remote-caching/external-ci-cd#openid-connect-oidc

Forks skip the step entirely since they won't have access to repository
variables. During outages or any other permission errors, the steps
outcome will simply be ignore and we fall back to uncached behavior.

This could lead to silent regressions or hiding new, incorrect callsites
lacking necessary permissions. A Datadog monitor is not as simple as I'd
like since DD does not track outcome but conclusion (which is always
success for continue-on-error). Adding custom tags via DD CLI feels to
heavy. We'll revisit if this becomes a recurring issue.
2026-08-20 10:16:10 +02:00

60 lines
2.1 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
# Default TURBO_API to Vercel's public API when the workflow does not set it.
if [ -z "${TURBO_API:-}" ]; then
export TURBO_API="https://api.vercel.com"
echo "TURBO_API=${TURBO_API}" >> "$GITHUB_ENV"
fi
# Exported by `vercel/setup-turborepo-remote-cache-action`, and unset entirely
# when that step was skipped. Bind them so the substring expansions below don't
# trip `set -u`, which rejects an unset name even in `${var:0:3}`.
TURBO_TOKEN="${TURBO_TOKEN:-}"
TURBO_TEAM="${TURBO_TEAM:-}"
if [ -z "$TURBO_TOKEN" ]; then
echo "WARNING: no TURBO_TOKEN available"
fi
echo "::add-mask::${TURBO_TOKEN}"
echo "Cache endpoint: ${TURBO_API:0:9}..."
echo "TURBO_TOKEN: ${TURBO_TOKEN:0:3}..."
echo "TURBO_TEAM: ${TURBO_TEAM}"
# Install vercel/sccache fork via cargo-binstall.
# cargo-binstall is installed by .github/actions/setup-rust.
cargo binstall --no-confirm --git https://github.com/vercel/sccache sccache
sccache --version
# Set env vars for the sccache server (export) and subsequent steps (GITHUB_ENV).
set_env() {
export "$1=$2"
echo "$1=$2" >> "$GITHUB_ENV"
}
# Temporary disable while we work out binstall issue
#set_env RUSTC_WRAPPER sccache
set_env SCCACHE_BASEDIRS "${INPUT_BASE_DIR:-${GITHUB_WORKSPACE}}"
set_env CARGO_INCREMENTAL 0
set_env SCCACHE_IDLE_TIMEOUT 0
set_env SCCACHE_DIR "${HOME}/.sccache"
set_env SCCACHE_RUST_CRATE_TYPE_ALLOW_HASH v1
set_env SCCACHE_ERROR_LOG "${RUNNER_TEMP:-/tmp}/sccache-error.log"
# Gracefully fall back to local compilation if the remote cache is unreachable.
set_env SCCACHE_IGNORE_SERVER_IO_ERROR 1
# Configure remote cache if token is available, otherwise disk-only.
if [ -n "${TURBO_TOKEN:-}" ]; then
set_env SCCACHE_MULTILEVEL_CHAIN "disk,vercel_artifacts"
set_env SCCACHE_VERCEL_ARTIFACTS_ENDPOINT "${TURBO_API}"
set_env SCCACHE_VERCEL_ARTIFACTS_TOKEN "${TURBO_TOKEN}"
set_env SCCACHE_VERCEL_ARTIFACTS_TEAM_SLUG "${TURBO_TEAM}"
fi
# Start the sccache daemon.
echo "SCCACHE_BASEDIRS=${SCCACHE_BASEDIRS}"
sccache --start-server 2>&1 || echo "WARNING: sccache failed to start"
sccache --show-stats 2>&1 | grep -E "Cache location|Base directories" || true