mirror of
https://github.com/block/buzz.git
synced 2026-10-27 12:40:30 +00:00
## Summary - roll every `Swatinem/rust-cache` use back from v2.9.2 to the last known-good v2.9.1 digest - give Unit Tests a new `sherpa-cache-v1` key so it cannot restore the existing poisoned artifact - pin Renovate to v2.9.1 and add CI contracts that reject unsafe cache actions or a misplaced generation key ## Why After #5441 upgraded rust-cache to v2.9.2, warm-cache `main` Unit Tests runs began failing while linking `buzz-voice` with `could not find native static library sherpa-onnx-c-api`. The failed run at `db5617dd1` restored the same 1.4 KB cache generation that had already failed at `01091c15a`; the preceding cold run at `26f4c3ed3` downloaded sherpa 1.13.4 and passed. v2.9.2 changed target cleanup, while `sherpa-onnx-sys` treats its prebuilt `lib/` directory as proof that the native archive exists. Rolling back the action and invalidating the affected key removes both sides of that failure state without disabling target caching. ## Validation At `6da0037a0407fc498cd482fcbbb74c7a15907e9f`: - `scripts/test-rust-cache-contract.sh` - `scripts/test-rust-cache-contract-regressions.sh` - negative fixtures reject a bad digest in a newly named `.yaml` workflow and a generation key moved outside the cache action's `with` block - YAML parse for all workflows - release, desktop candidate, mobile release, mobile candidate, and mobile worktree source contracts - `just file-size-check` - pre-commit and pre-push hooks The PR Unit Tests run proves the cold-cache path because pull requests restore but do not save Rust caches. The first successful `main` run after merge will save the new Unit Tests key; the following `main` run will exercise the warm restore. ## Related issue None found. Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
162 lines
3.9 KiB
Bash
Executable File
162 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
root=$(cd "$(dirname "$0")/.." && pwd)
|
|
known_good='e18b497796c12c097a38f9edb9d0641fb99eee32'
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
mkdir -p "$tmp/.github/workflows"
|
|
cp "$root"/.github/workflows/*.yml "$tmp/.github/workflows/"
|
|
for workflow in "$root"/.github/workflows/*.yaml; do
|
|
[[ -e "$workflow" ]] || continue
|
|
cp "$workflow" "$tmp/.github/workflows/"
|
|
done
|
|
cp "$root/renovate.json" "$tmp/renovate.json"
|
|
|
|
run_contract() {
|
|
BUZZ_RUST_CACHE_CONTRACT_ROOT="$tmp" "$root/scripts/test-rust-cache-contract.sh"
|
|
}
|
|
|
|
expect_failure() {
|
|
local expected=$1
|
|
local output
|
|
if output=$(run_contract 2>&1); then
|
|
echo "expected rust cache contract failure containing: $expected" >&2
|
|
exit 1
|
|
fi
|
|
if [[ "$output" != *"$expected"* ]]; then
|
|
printf 'unexpected rust cache contract error:\n%s\n' "$output" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
write_cache_workflow() {
|
|
cat > "$tmp/.github/workflows/new-cache-user.yaml"
|
|
}
|
|
|
|
run_contract >/dev/null
|
|
|
|
write_cache_workflow <<'YAML'
|
|
name: Bad digest
|
|
on: workflow_dispatch
|
|
jobs:
|
|
cache:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6
|
|
YAML
|
|
expect_failure 'restored rust-cache v2.9.2'
|
|
|
|
write_cache_workflow <<'YAML'
|
|
name: Mutable tag
|
|
on: workflow_dispatch
|
|
jobs:
|
|
cache:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: Swatinem/rust-cache@v2
|
|
YAML
|
|
expect_failure 'rust-cache must stay on the v2.9.1 digest'
|
|
|
|
write_cache_workflow <<'YAML'
|
|
name: Expression ref
|
|
on: workflow_dispatch
|
|
jobs:
|
|
cache:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: Swatinem/rust-cache@${{ matrix.cache-ref }}
|
|
YAML
|
|
expect_failure 'rust-cache must stay on the v2.9.1 digest'
|
|
|
|
write_cache_workflow <<'YAML'
|
|
name: Spaced key
|
|
on: workflow_dispatch
|
|
jobs:
|
|
cache:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses : Swatinem/rust-cache@v2
|
|
YAML
|
|
expect_failure 'rust-cache must stay on the v2.9.1 digest'
|
|
|
|
write_cache_workflow <<'YAML'
|
|
name: Flow mapping
|
|
on: workflow_dispatch
|
|
jobs:
|
|
cache:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- { uses: Swatinem/rust-cache@v2 }
|
|
YAML
|
|
expect_failure 'rust-cache must stay on the v2.9.1 digest'
|
|
|
|
write_cache_workflow <<'YAML'
|
|
name: Quoted key
|
|
on: workflow_dispatch
|
|
jobs:
|
|
cache:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- "uses": Swatinem/rust-cache@v2
|
|
YAML
|
|
expect_failure 'rust-cache must stay on the v2.9.1 digest'
|
|
rm "$tmp/.github/workflows/new-cache-user.yaml"
|
|
|
|
mkdir -p "$tmp/.github/actions/cache"
|
|
cat > "$tmp/.github/actions/cache/action.yml" <<'YAML'
|
|
name: Unsafe cache wrapper
|
|
runs:
|
|
using: composite
|
|
steps:
|
|
- { uses: Swatinem/rust-cache@v2 }
|
|
YAML
|
|
write_cache_workflow <<'YAML'
|
|
name: Local cache wrapper
|
|
on: workflow_dispatch
|
|
jobs:
|
|
cache:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: ./.github/actions/cache
|
|
YAML
|
|
expect_failure 'rust-cache must stay on the v2.9.1 digest'
|
|
|
|
cat > "$tmp/.github/actions/cache/action.yml" <<YAML
|
|
name: Safe preferred cache wrapper
|
|
runs:
|
|
using: composite
|
|
steps:
|
|
- uses: Swatinem/rust-cache@$known_good
|
|
YAML
|
|
cat > "$tmp/.github/actions/cache/action.yaml" <<'YAML'
|
|
name: Unreachable stale cache wrapper
|
|
runs:
|
|
using: composite
|
|
steps:
|
|
- uses: Swatinem/rust-cache@v2
|
|
YAML
|
|
run_contract >/dev/null
|
|
rm -rf "$tmp/.github/actions" "$tmp/.github/workflows/new-cache-user.yaml"
|
|
|
|
python3 - "$tmp/.github/workflows/ci.yml" <<'PY'
|
|
import pathlib
|
|
import sys
|
|
|
|
path = pathlib.Path(sys.argv[1])
|
|
workflow = path.read_text()
|
|
needle = " key: sherpa-cache-v1\n save-if:"
|
|
replacement = " save-if:"
|
|
if workflow.count(needle) != 1:
|
|
raise SystemExit("expected one Unit Tests cache generation key")
|
|
workflow = workflow.replace(needle, replacement)
|
|
job = " unit-tests:\n"
|
|
if workflow.count(job) != 1:
|
|
raise SystemExit("expected one Unit Tests job")
|
|
workflow = workflow.replace(job, job + " env:\n key: sherpa-cache-v1\n", 1)
|
|
path.write_text(workflow)
|
|
PY
|
|
expect_failure 'rust-cache action must keep with.key set to sherpa-cache-v1'
|
|
|
|
echo "rust cache contract regressions passed"
|