Skip to content

Commit 26fd0a3

Browse files
authored
chore(ci): use namesapce managed sccache (#5013)
1 parent afafcd9 commit 26fd0a3

11 files changed

Lines changed: 284 additions & 101 deletions

File tree

.github/workflows/cargo_workspace_dependency_check.yml

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ jobs:
3131
uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0
3232
with:
3333
cache: rust
34-
path: |-
35-
/home/runner/.cache/sccache
36-
/nix
34+
path: /nix
3735
continue-on-error: true
3836
- name: Setup Nix
3937
uses: './.github/actions/setup-nix'
@@ -42,10 +40,34 @@ jobs:
4240
with:
4341
cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }}
4442
dev-shell: 'true'
45-
- name: Point sccache at the cache volume
43+
- name: Configure Namespace remote sccache
44+
if: (github.event_name != 'pull_request' && github.event_name != 'pull_request_target') || github.event.pull_request.head.repo.full_name == github.repository
4645
run: |-
47-
echo "SCCACHE_DIR=/home/runner/.cache/sccache" >> "$GITHUB_ENV"
48-
echo "SCCACHE_CACHE_SIZE=20G" >> "$GITHUB_ENV"
46+
set -euo pipefail
47+
env_file="$(mktemp "$RUNNER_TEMP/namespace-sccache.XXXXXX")"
48+
trap 'rm -f "$env_file"' EXIT
49+
if nsc cache sccache setup --cache_name sccache-ci > "$env_file"; then
50+
# Register credential values as masked BEFORE exporting: GitHub only
51+
# masks `secrets.*`, so without this SCCACHE_WEBDAV_TOKEN — a broad,
52+
# ~24h Namespace workspace token (registry + cache write) — printed
53+
# verbatim in every subsequent step's env dump. Masking is selective by
54+
# key name: masking non-secrets like the endpoint URL or key prefix
55+
# would redact those strings everywhere in the logs.
56+
while IFS= read -r line; do
57+
k="${line%%=*}"
58+
v="${line#*=}"
59+
[ -n "$v" ] && [ "$k" != "$line" ] || continue
60+
case "$k" in
61+
*TOKEN*|*SECRET*|*PASSWORD*) echo "::add-mask::$v" ;;
62+
esac
63+
done < "$env_file"
64+
cat "$env_file" >> "$GITHUB_ENV"
65+
# Force the next compiler invocation to start a server with the new remote
66+
# backend even if a setup hook happened to launch one already.
67+
sccache --stop-server >/dev/null 2>&1 || true
68+
else
69+
echo "::warning::Namespace remote sccache setup failed; using local cache fallback"
70+
fi
4971
- name: install tool
5072
run: cargo install cargo-workspace-dependency-checker@1.0.1
5173
- name: check
@@ -65,9 +87,7 @@ jobs:
6587
uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0
6688
with:
6789
cache: rust
68-
path: |-
69-
/home/runner/.cache/sccache
70-
/nix
90+
path: /nix
7191
continue-on-error: true
7292
- name: Setup Nix
7393
uses: './.github/actions/setup-nix'
@@ -76,10 +96,34 @@ jobs:
7696
with:
7797
cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }}
7898
dev-shell: 'true'
79-
- name: Point sccache at the cache volume
99+
- name: Configure Namespace remote sccache
100+
if: (github.event_name != 'pull_request' && github.event_name != 'pull_request_target') || github.event.pull_request.head.repo.full_name == github.repository
80101
run: |-
81-
echo "SCCACHE_DIR=/home/runner/.cache/sccache" >> "$GITHUB_ENV"
82-
echo "SCCACHE_CACHE_SIZE=20G" >> "$GITHUB_ENV"
102+
set -euo pipefail
103+
env_file="$(mktemp "$RUNNER_TEMP/namespace-sccache.XXXXXX")"
104+
trap 'rm -f "$env_file"' EXIT
105+
if nsc cache sccache setup --cache_name sccache-ci > "$env_file"; then
106+
# Register credential values as masked BEFORE exporting: GitHub only
107+
# masks `secrets.*`, so without this SCCACHE_WEBDAV_TOKEN — a broad,
108+
# ~24h Namespace workspace token (registry + cache write) — printed
109+
# verbatim in every subsequent step's env dump. Masking is selective by
110+
# key name: masking non-secrets like the endpoint URL or key prefix
111+
# would redact those strings everywhere in the logs.
112+
while IFS= read -r line; do
113+
k="${line%%=*}"
114+
v="${line#*=}"
115+
[ -n "$v" ] && [ "$k" != "$line" ] || continue
116+
case "$k" in
117+
*TOKEN*|*SECRET*|*PASSWORD*) echo "::add-mask::$v" ;;
118+
esac
119+
done < "$env_file"
120+
cat "$env_file" >> "$GITHUB_ENV"
121+
# Force the next compiler invocation to start a server with the new remote
122+
# backend even if a setup hook happened to launch one already.
123+
sccache --stop-server >/dev/null 2>&1 || true
124+
else
125+
echo "::warning::Namespace remote sccache setup failed; using local cache fallback"
126+
fi
83127
- name: generated dependency artifacts are up to date
84128
run: |
85129
cargo run -p xtask --locked -- deps --check

.github/workflows/code_check_cloud_storage.yml

Lines changed: 56 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.github/workflows/preview-fly.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ jobs:
4747
with:
4848
cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }}
4949
- name: Configure Namespace remote sccache
50+
if: (github.event_name != 'pull_request' && github.event_name != 'pull_request_target') || github.event.pull_request.head.repo.full_name == github.repository
5051
run: |-
5152
set -euo pipefail
52-
env_file="$RUNNER_TEMP/namespace-sccache.env"
53+
env_file="$(mktemp "$RUNNER_TEMP/namespace-sccache.XXXXXX")"
54+
trap 'rm -f "$env_file"' EXIT
5355
if nsc cache sccache setup --cache_name fly-preview > "$env_file"; then
5456
# Register credential values as masked BEFORE exporting: GitHub only
5557
# masks `secrets.*`, so without this SCCACHE_WEBDAV_TOKEN — a broad,

.github/workflows/web-app-check-main.yml

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,20 +66,42 @@ jobs:
6666
uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0
6767
with:
6868
cache: bun,rust
69-
path: |-
70-
/home/runner/.cache/sccache
71-
/nix
69+
path: /nix
7270
continue-on-error: true
7371
- name: Setup Nix
7472
uses: './.github/actions/setup-nix'
7573
- name: Setup Prereqs
7674
uses: './.github/actions/setup-reqs-web'
7775
with:
7876
cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }}
79-
- name: Point sccache at the cache volume
77+
- name: Configure Namespace remote sccache
78+
if: ((github.event_name != 'pull_request' && github.event_name != 'pull_request_target') || github.event.pull_request.head.repo.full_name == github.repository) && (needs.path-check.outputs.api_changed == 'true')
8079
run: |-
81-
echo "SCCACHE_DIR=/home/runner/.cache/sccache" >> "$GITHUB_ENV"
82-
echo "SCCACHE_CACHE_SIZE=20G" >> "$GITHUB_ENV"
80+
set -euo pipefail
81+
env_file="$(mktemp "$RUNNER_TEMP/namespace-sccache.XXXXXX")"
82+
trap 'rm -f "$env_file"' EXIT
83+
if nsc cache sccache setup --cache_name web-ci > "$env_file"; then
84+
# Register credential values as masked BEFORE exporting: GitHub only
85+
# masks `secrets.*`, so without this SCCACHE_WEBDAV_TOKEN — a broad,
86+
# ~24h Namespace workspace token (registry + cache write) — printed
87+
# verbatim in every subsequent step's env dump. Masking is selective by
88+
# key name: masking non-secrets like the endpoint URL or key prefix
89+
# would redact those strings everywhere in the logs.
90+
while IFS= read -r line; do
91+
k="${line%%=*}"
92+
v="${line#*=}"
93+
[ -n "$v" ] && [ "$k" != "$line" ] || continue
94+
case "$k" in
95+
*TOKEN*|*SECRET*|*PASSWORD*) echo "::add-mask::$v" ;;
96+
esac
97+
done < "$env_file"
98+
cat "$env_file" >> "$GITHUB_ENV"
99+
# Force the next compiler invocation to start a server with the new remote
100+
# backend even if a setup hook happened to launch one already.
101+
sccache --stop-server >/dev/null 2>&1 || true
102+
else
103+
echo "::warning::Namespace remote sccache setup failed; using local cache fallback"
104+
fi
83105
- name: Generate API Types
84106
if: needs.path-check.outputs.api_changed == 'true'
85107
run: bun run gen-api -- --check

tooling/xtask/crates/xtask_workflows/src/workflows/cargo_workspace_dependency_check.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
//! dep-closure map. Generated into `cargo_workspace_dependency_check.yml`
44
//! (replaces the hand-written `cargo-workspace-dependency-check.yml`).
55
//!
6-
//! Both jobs build Rust, so they run on the rust-ci profile with the shared
7-
//! `sccache-ci` volume and the Nix dev shell — this replaces the deprecated
8-
//! `actions-rs/toolchain` + hardcoded `rustup default 1.85` (which drifted
9-
//! from the workspace toolchain) and gives the `cargo install`/xtask builds
10-
//! warm caches instead of compiling cold on every run.
6+
//! Both jobs build Rust, so they run on the rust-ci profile with the Nix/Cargo
7+
//! cache volume and Namespace's shared `sccache-ci` remote cache. This replaces
8+
//! the deprecated `actions-rs/toolchain` + hardcoded `rustup default 1.85`
9+
//! (which drifted from the workspace toolchain) and gives the `cargo install`
10+
//! and xtask builds warm caches instead of compiling cold on every run.
1111
1212
use gh_workflow::{
1313
Concurrency, Event, Expression, Job, PullRequest, PullRequestType, Run, Step, Use, Workflow,
@@ -57,7 +57,7 @@ fn rust_ci_job() -> Job {
5757
.add_step(steps::mount_cache_volume())
5858
.add_step(steps::setup_nix())
5959
.add_step(steps::setup_dev_shell())
60-
.add_step(steps::pin_sccache_dir())
60+
.add_step(steps::configure_namespace_sccache(vars::CI_SCCACHE_NAME))
6161
}
6262

6363
fn dependency_check() -> Job {
@@ -88,7 +88,7 @@ fn checkout() -> Step<Use> {
8888

8989
/// `cargo install` skips the build when the same version is already present
9090
/// in `~/.cargo/bin` (persisted on the cache volume); cold installs compile
91-
/// through the volume-backed sccache.
91+
/// through Namespace's remote sccache.
9292
fn install_checker() -> Step<Run> {
9393
Step::new("install tool").run("cargo install cargo-workspace-dependency-checker@1.0.1")
9494
}

tooling/xtask/crates/xtask_workflows/src/workflows/code_check_cloud_storage.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
//! workspace on pull requests. Generated into `code-check-cloud-storage.yml`.
33
//!
44
//! Ported from the hand-written workflow, with two infra changes: the runners
5-
//! moved to Namespace profiles, and sccache moved off the S3 bucket onto a
6-
//! persisted Namespace cache volume (so there are no AWS credentials anywhere).
5+
//! moved to Namespace profiles, and compiled objects moved off the S3/local
6+
//! volume backends onto Namespace's official remote sccache (so there are no
7+
//! AWS credentials anywhere).
78
89
use gh_workflow::{
910
Container, Env, Event, Expression, Job, Port, PullRequest, PullRequestType, Run, Step, Workflow,
@@ -69,7 +70,7 @@ fn check() -> Job {
6970
.add_step(steps::mount_cache_volume())
7071
.add_step(steps::setup_nix())
7172
.add_step(steps::setup_dev_shell())
72-
.add_step(steps::pin_sccache_dir())
73+
.add_step(steps::configure_namespace_sccache(vars::CI_SCCACHE_NAME))
7374
.add_step(validate_doppler_configs())
7475
.add_step(cargo_fmt())
7576
.add_step(cargo_clippy())
@@ -92,7 +93,7 @@ fn test() -> Job {
9293
.add_step(steps::mount_cache_volume())
9394
.add_step(steps::setup_nix())
9495
.add_step(steps::setup_dev_shell())
95-
.add_step(steps::pin_sccache_dir())
96+
.add_step(steps::configure_namespace_sccache(vars::CI_SCCACHE_NAME))
9697
.add_step(configure_postgres())
9798
.add_step(prepare_tests())
9899
.add_step(run_tests())
@@ -186,9 +187,9 @@ fn compute_nextest_filter() -> Step<Run> {
186187
.shell("bash")
187188
}
188189

189-
/// Build and run the Doppler config binaries affected by this PR. (sccache is
190-
/// local now, so this no longer needs AWS credentials only the assertion that
191-
/// `RUSTC_WRAPPER` is wired stays.)
190+
/// Build and run the Doppler config binaries affected by this PR. Namespace's
191+
/// remote sccache needs no AWS credentials; only the assertion that
192+
/// `RUSTC_WRAPPER` is wired stays.
192193
fn validate_doppler_configs() -> Step<Run> {
193194
Step::new("validate Doppler configs")
194195
.run(include_str!("scripts/validate_doppler_configs.sh"))
@@ -207,7 +208,7 @@ fn cargo_fmt() -> Step<Run> {
207208
Step::new("fmt").run("cargo fmt --check")
208209
}
209210

210-
/// `cargo clippy` (no AWS creds — sccache is local).
211+
/// `cargo clippy` (no AWS credentials; sccache uses Namespace's remote cache).
211212
fn cargo_clippy() -> Step<Run> {
212213
Step::new("clippy").run(indoc::indoc! {r#"
213214
cargo clippy --workspace --all-features \
@@ -259,7 +260,7 @@ fn prepare_tests() -> Step<Run> {
259260
Step::new("prepare tests").run("just setup_test_envs && just initialize_dbs")
260261
}
261262

262-
/// Run the test suite (no AWS creds — sccache is local).
263+
/// Run the test suite (no AWS credentials; sccache uses Namespace's remote cache).
263264
fn run_tests() -> Step<Run> {
264265
Step::new("run tests").run(include_str!("scripts/run_tests.sh"))
265266
}

tooling/xtask/crates/xtask_workflows/src/workflows/runners.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
//! We run on Namespace (namespace.so) hosted runners, selected by the dashboard
44
//! *profile* name — the same convention the deploy workflows already use. Each
55
//! profile's persisted cache volume is configured in the Namespace dashboard;
6-
//! that volume backs the sccache + cargo caches (see
6+
//! that volume backs Cargo/Nix state while compiled objects use Namespace's
7+
//! official remote sccache (see
78
//! [`crate::workflows::steps::mount_cache_volume`]).
89
910
use std::fmt;
@@ -22,7 +23,7 @@ pub enum Runner {
2223
Mid,
2324
/// Dedicated CI profile for the heavy compile + test jobs. Has its own
2425
/// cache volume, isolated from the deploy profiles so deploy's churn can't
25-
/// evict the CI sccache/cargo caches.
26+
/// evict the CI Cargo/Nix caches.
2627
RustCi,
2728
}
2829

@@ -45,9 +46,8 @@ impl Runner {
4546
/// branch can only inherit the *default* branch's cache, so any branch whose
4647
/// workflow never runs on `main` starts cold every time. Pinning a fixed tag
4748
/// makes every branch read/write the *same* volume — one global cache, like
48-
/// the old shared S3 sccache bucket. sccache entries are content-addressed,
49-
/// so concurrent writers never corrupt each other; the worst case is an
50-
/// occasional miss that simply recompiles.
49+
/// the old globally shared cache behavior. Cache-volume writes are managed
50+
/// by Namespace; compiled objects use the separately named remote sccache.
5151
pub fn with_cache_tag(self, tag: &str) -> String {
5252
format!("{self};overrides.cache-tag={tag}")
5353
}

0 commit comments

Comments
 (0)