Repository navigation
Conversation
ChristianPavilonis
left a comment
There was a problem hiding this comment.
😃 Approving the cache-seed hardening while keeping deployment smoke jobs independent of cache probes.
🤔 One non-blocking concern remains: compiler write counters can report success despite failed remote finalization. A bounded remote read-back hit and finalization-failure coverage would close that publication gap; details are inline.
| if jq -e '((.stats.cache_hits.counts.Rust // 0) + (.stats.cache_writes // 0)) > 0 and (.stats.cache_errors.counts.Rust // 0) == 0 and (.stats.cache_read_errors // 0) == 0 and (.stats.cache_write_errors // 0) == 0' <<<"$stats" >/dev/null; then | ||
| break | ||
| fi |
There was a problem hiding this comment.
[P2] Verify compiler publication with a remote read-back hit
A successful write counter does not establish publication with the pinned backend. sccache v0.16.0 uses OpenDAL 0.55.0, whose GHAC-v2 writer discards errors from FinalizeCacheEntryUpload. When uploads succeed but finalization returns 503, cache_writes becomes 1 while cache_write_errors remains 0. Reproduced with the real pinned binary and Rust 1.98.1 against a local cache-v2 service: both targets were accepted on attempt 1 and the seed exited 0, but the fresh-target compiler-reuse check exited 1. This bypasses the new retries for unpublished entries and leaves the downstream smoke job failing. Require a bounded remote read-back hit before accepting a new write, and add finalization-failure coverage.
dhruv8sh
left a comment
There was a problem hiding this comment.
PR Review
Summary
This PR checks that the cache-probe seed actually publishes its compiler, source and target caches, with bounded retries, while the deploy and release jobs stay independent of it. The change is well-scoped and thoroughly covered by mutation tests. Approving.
😃 Praise
- 😃 The final check doesn't trust
fail-on-cache-missalone: the "Require exact … seed publication" steps demand a literaltruefrom one of the lookup outputs, and all 16 input combinations are exercised (fixture.sh:85-97). This coversactions/cachev5 returning early without applyingfail-on-cache-miss. - Inline: workflow mutation guards (
publication.sh) and confined directory cleanup (seed-compiler-cache.sh).
Findings
Blocking
None.
Non-blocking
- 🤔 A cache-outage run can add up to about 8 minutes: retry waits are 60s then 120s per target (360s for native plus WASM), and the source and target saves can each add another 60s. That's acceptable because only the cache-probe jobs are affected, not the deploy jobs. Just confirming the bound is intended (
seed-compiler-cache.sh:40). - 📝 Release jobs were already independent on
main:fixture-releaseandstore-free-releasealready had noneeds. The new assertion infixture.sh:44-47locks that in as a regression guard. - 📝 A duplicate source-cache save is harmless: when there is no exact source-cache hit (including a partial match through
restore-keys), the action's post-job hook tries to save the same key again and the cache rejects it with a warning only. The workflow comment already explains this. - Inline: ♻️ the source cache paths are copied four times; ⛏ the deploy workflow runs a script from a
tests/directory.
CI Status
- fmt: PASS
- clippy: PASS
- tests: PASS
tests/seed.sh: PASS (fixture.shandpublication.shwere not run locally becauseyqisn't installed; the hosted checks pass)
| source "$ACTION_DIR/tests/common.sh" | ||
| workflow="$ACTION_DIR/../../workflows/deploy-action.yml" | ||
|
|
||
| reject_mutation() { |
There was a problem hiding this comment.
😃 Workflow guards are themselves tested by breaking the workflow: making 38 deliberate edits to the workflow and requiring each one to fail fixture.sh with the matching error message proves the guards actually catch the problems, not just that they run.
|
|
||
| # Publish each target before downstream jobs test first-build compiler reuse. | ||
| fixture="${GITHUB_WORKSPACE:?}/cache-restore-fixture" | ||
| target_dir=$(realpath "${CARGO_TARGET_DIR:?}") |
There was a problem hiding this comment.
😃 Directory cleanup is safely confined: the target path is resolved and must be exactly the fixture directory, unsafe host target names are rejected, and symlinked target or debug directories are refused before rm -rf. seed.sh checks that marker files outside the directory survive every symlink and .. attempt.
| id: source-save-1 | ||
| uses: actions/cache/save@v5 | ||
| with: | ||
| path: | |
There was a problem hiding this comment.
♻️ Source cache paths are copied four times: the three-line ~/.cargo/... path list is repeated in all four source save and lookup steps. fixture.sh already compares each copy against action.yml, so drift would be caught; this is about readability only.
Fix (optional): use a YAML anchor (path: &cargo_source_paths | …, then path: *cargo_source_paths), which GitHub Actions now supports.
|
|
||
| - name: Seed native and WASM compiler outputs | ||
| working-directory: cache-restore-fixture | ||
| run: bash .github/actions/setup-rust-build-cache/tests/seed-compiler-cache.sh |
There was a problem hiding this comment.
⛏ The deploy workflow runs a script from a tests/ directory: seed-compiler-cache.sh is real CI logic invoked by the cache-restore-seed job. It sits next to the test scripts, as make-fixture.sh and setup-toolchain.sh already do, so this follows the existing pattern. Optionally add a header comment noting the workflow calls this script and seed.sh covers it.
Summary
fail-on-cache-miss.Changes
setup-rust-build-cache/tests/seed-compiler-cache.shsetup-rust-build-cache/tests/seed.shsetup-rust-build-cache/tests/{fixture,publication,run}.sh.github/workflows/deploy-action.ymlfail-on-cache-missdiagnostics and enforce an exact lookup-hit assertion. Exhaustion fails only the cache-probe chain.Closes
Closes #433
Test plan
Verified locally with Rust 1.98.1 after the independent review corrections:
cargo test --workspace --all-targetscargo clippy --workspace --all-targets --all-features -- -D warningscargo fmt --all -- --checkcargo check --workspace --all-targets --features "fastly cloudflare spin"cargo check -p edgezero-adapter-spin --target wasm32-wasip2 --features spinbash .github/actions/setup-rust-build-cache/tests/run.sh— action, revision, review, fixture, workflow mutation and seed regressions pass.git diff --check.3373552e, including cache publication/reuse and deployment smoke jobs, runtime tests and CodeQL.Compiler seed retry backoff can add up to 180 seconds per target; source and target publication can each add 60 seconds. These waits affect only the cache-probe chain.
Review decisions
The review reproduced three publication/cleanup gaps and fixed all three:
actions/cachev5 restore can return success withcache-hit=falsebefore parsingfail-on-cache-misswhen feature availability fails. The final shell gate therefore requirestruefrom one of the actual lookup outputs. Tests check both the expressions feeding that gate and its behavior; the assertion is not redundant.rm -rfoutside it. Cleanup now rejects namespace/debug symlinks and unsafe host components; tests preserve sentinels outside the confined directory.The existing compiler retry strategy remains: pinned sccache v0.16.0 waits for cache writes before reporting compilation completion. Immediate stats inspection is valid, and an existing hit proves publication. Polling/restarting the server is unnecessary. Moving each attempt to another target directory would complicate compiler-cache identity and final archive ownership; guarded cleanup preserves the existing layout.
Local mutation tests simulate publication failures without relying on live outages. Hosted happy-path checks do not prove recovery during an actual cache-service outage.
Checklist
CLAUDE.md; changes limited to cache CI/tooling.