diff --git a/.github/actions/rust-build-cache/configure.mjs b/.github/actions/rust-build-cache/configure.mjs index 15984cb82..dd88047ad 100644 --- a/.github/actions/rust-build-cache/configure.mjs +++ b/.github/actions/rust-build-cache/configure.mjs @@ -138,7 +138,10 @@ export function configure(env = process.env, compilerVersion, probe = probeRemot }); const cargoHome = env.CARGO_HOME || path.join(homedir(), '.cargo'); const write = cacheWriter(env.CACHE_SAVE_IF || 'auto', env.GITHUB_REF, env.CACHE_DEFAULT_BRANCH, env.GITHUB_EVENT_NAME); - const remote = remoteCompilerCache(env, write); + // save-if opts a lane out of the Actions cache budget; R2 has no such budget, + // so every trusted default-branch run writes the shared compiler cache. + const trusted = cacheWriter('auto', env.GITHUB_REF, env.CACHE_DEFAULT_BRANCH, env.GITHUB_EVENT_NAME); + const remote = remoteCompilerCache(env, trusted); let remoteValues = {}; let compilerCacheLocation = `local disk (${remote.reason})`; if (remote.values) { diff --git a/.github/actions/rust-build-cache/configure.test.mjs b/.github/actions/rust-build-cache/configure.test.mjs index 245ca9b3b..3cebe7dfa 100644 --- a/.github/actions/rust-build-cache/configure.test.mjs +++ b/.github/actions/rust-build-cache/configure.test.mjs @@ -198,6 +198,16 @@ test('configuration enables R2 only after the probe succeeds and exports nothing 'rustc test fixture', () => ({ ok: true, detail: 'HTTP 404' })); assert.equal(pull.SCCACHE_S3_RW_MODE, 'READ_ONLY'); + // An Actions-cache opt-out lane on main still writes the shared compiler cache. + const optedOut = configure({ ...env, CACHE_SAVE_IF: 'false', GITHUB_ENV: path.join(temp, 'env-opt-out') }, + 'rustc test fixture', () => ({ ok: true, detail: 'HTTP 404' })); + assert.equal(optedOut.HYPERCOLOR_CACHE_WRITE, 'false'); + assert.equal(optedOut.SCCACHE_S3_RW_MODE, 'READ_WRITE'); + const optedOutPull = configure({ ...env, CACHE_SAVE_IF: 'false', GITHUB_REF: 'refs/pull/7/merge', + GITHUB_EVENT_NAME: 'pull_request', GITHUB_ENV: path.join(temp, 'env-opt-out-pr') }, + 'rustc test fixture', () => ({ ok: true, detail: 'HTTP 404' })); + assert.equal(optedOutPull.SCCACHE_S3_RW_MODE, 'READ_ONLY'); + const down = configure({ ...env, GITHUB_ENV: path.join(temp, 'env-down') }, 'rustc test fixture', () => ({ ok: false, detail: 'HTTP 403' })); assert.equal(down.SCCACHE_BUCKET, undefined); assert.equal(down.AWS_SECRET_ACCESS_KEY, undefined); diff --git a/docs/development/SERVO_BUILD_CACHING.md b/docs/development/SERVO_BUILD_CACHING.md index ec59fef1a..4d0833a1e 100644 --- a/docs/development/SERVO_BUILD_CACHING.md +++ b/docs/development/SERVO_BUILD_CACHING.md @@ -186,9 +186,11 @@ Each of the thirteen jobs that use the cache action passes the bucket, the `SCCACHE_R2_SECRET_ACCESS_KEY` secrets as the action's `r2-*` inputs. Jobs that never compile see none of them. The action then: -- writes (`SCCACHE_S3_RW_MODE=READ_WRITE`) only where the Actions cache writes, - and reads everywhere else, so pull requests and tags reuse what `main` - compiled without adding entries; +- writes (`SCCACHE_S3_RW_MODE=READ_WRITE`) from every push or dispatch on + `main`, including lanes that set `save-if: "false"` (that switch protects + the Actions cache budget, which R2 does not share), and reads everywhere + else, so pull requests and tags reuse what `main` compiled without adding + entries; - keys entries under `sccache/-`, so each runner platform keeps its own namespace; - sends a signed HEAD request before enabling R2. A refused or unreachable @@ -201,8 +203,9 @@ Fork pull requests receive no secrets and compile with the local disk cache. The `Compiler cache:` line in the configure step's log and the `Cache location` row of the job summary's statistics show which backend a job used. The statistics are authoritative: a mid-job fallback, or a write check -that downgrades sccache to read-only, leaves the configure line stale, and the -first `main` run should show `Cache writes` above zero. A read-only run counts +that downgrades sccache to read-only, leaves the configure line stale. +sccache 0.17 has no write counter, so a writing run shows a nonzero +`Average cache write` with `Cache write errors` at zero. A read-only run counts every write it skips as a `Cache write errors` entry, so in pull requests and tags that row matching `Cache misses` is expected, not a fault.