| 1 | #!/usr/bin/env bash |
| 2 | set -euo pipefail |
| 3 | |
| 4 | repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" |
| 5 | script="${repo_root}/scripts/release/prune-actions-caches.sh" |
| 6 | tmp_dir="$(mktemp -d)" |
| 7 | trap 'rm -rf "${tmp_dir}"' EXIT |
| 8 | |
| 9 | # Fake gh: serves the cache listing (filtered by &ref= like the real API), |
| 10 | # PR states, and records DELETE calls. The caller's --jq filter runs through |
| 11 | # the real jq so the timestamp parsing is exercised too. |
| 12 | fake_gh="${tmp_dir}/gh" |
| 13 | cat > "${fake_gh}" <<'EOF' |
| 14 | #!/usr/bin/env bash |
| 15 | set -euo pipefail |
| 16 | [[ "$1" == "api" ]] || { echo "unexpected: $*" >&2; exit 9; } |
| 17 | shift |
| 18 | if [[ "$1" == "-X" ]]; then |
| 19 | [[ "$2" == "DELETE" ]] || exit 9 |
| 20 | echo "$3" >> "${FIXTURE_DIR}/deleted" |
| 21 | exit 0 |
| 22 | fi |
| 23 | [[ "$1" == "--paginate" ]] && shift |
| 24 | path="$1" |
| 25 | filter="$3" |
| 26 | case "${path}" in |
| 27 | */actions/caches\?*) |
| 28 | ref="" |
| 29 | if [[ "${path}" == *"&ref="* ]]; then ref="${path#*&ref=}"; fi |
| 30 | jq --arg ref "${ref}" '{actions_caches: [.actions_caches[] | select($ref == "" or .ref == $ref)]}' \ |
| 31 | "${FIXTURE_DIR}/caches.json" | jq -r "${filter}" |
| 32 | ;; |
| 33 | */pulls/*) |
| 34 | pr="${path##*/}" |
| 35 | jq ".\"${pr}\"" "${FIXTURE_DIR}/pulls.json" | jq -r "${filter}" |
| 36 | ;; |
| 37 | *) echo "unexpected path: ${path}" >&2; exit 9 ;; |
| 38 | esac |
| 39 | EOF |
| 40 | chmod +x "${fake_gh}" |
| 41 | export PRUNE_CACHES_GH="${fake_gh}" |
| 42 | export FIXTURE_DIR="${tmp_dir}" |
| 43 | export GH_REPO="owner/repo" |
| 44 | # 2026-09-22T12:00:00Z |
| 45 | export PRUNE_CACHES_NOW=1790078400 |
| 46 | |
| 47 | cat > "${tmp_dir}/caches.json" <<'EOF' |
| 48 | {"actions_caches":[ |
| 49 | {"id":1,"ref":"refs/pull/10/merge","size_in_bytes":100,"last_accessed_at":"2026-09-22T11:00:00.123Z"}, |
| 50 | {"id":2,"ref":"refs/pull/10/merge","size_in_bytes":200,"last_accessed_at":"2026-09-22T11:30:00Z"}, |
| 51 | {"id":3,"ref":"refs/pull/11/merge","size_in_bytes":400,"last_accessed_at":"2026-09-22T11:00:00Z"}, |
| 52 | {"id":4,"ref":"refs/heads/main","size_in_bytes":800,"last_accessed_at":"2026-09-01T00:00:00Z"}, |
| 53 | {"id":5,"ref":"refs/tags/v0.10.0","size_in_bytes":1600,"last_accessed_at":"2026-09-20T00:00:00.5Z"}, |
| 54 | {"id":6,"ref":"refs/tags/v0.10.1","size_in_bytes":3200,"last_accessed_at":"2026-09-22T10:00:00Z"} |
| 55 | ]} |
| 56 | EOF |
| 57 | echo '{"10":{"state":"closed"},"11":{"state":"open"}}' > "${tmp_dir}/pulls.json" |
| 58 | |
| 59 | deleted_ids() { |
| 60 | if [[ -f "${tmp_dir}/deleted" ]]; then |
| 61 | sed 's#.*/##' "${tmp_dir}/deleted" | sort -n | tr '\n' ' ' |
| 62 | fi |
| 63 | rm -f "${tmp_dir}/deleted" |
| 64 | } |
| 65 | |
| 66 | fail() { echo "FAIL: $*" >&2; exit 1; } |
| 67 | |
| 68 | # 1. --ref deletes exactly that ref's caches. |
| 69 | "${script}" --ref refs/pull/10/merge > "${tmp_dir}/out" |
| 70 | [[ "$(deleted_ids)" == "1 2 " ]] || fail "--ref pull/10 deleted the wrong set" |
| 71 | grep -q "deleted 2 caches, 300 bytes" "${tmp_dir}/out" || fail "--ref summary" |
| 72 | |
| 73 | # 2. --sweep: closed PR 10 and the day-old tag go; open PR 11, main and the |
| 74 | # fresh tag stay. |
| 75 | "${script}" --sweep > "${tmp_dir}/out" |
| 76 | [[ "$(deleted_ids)" == "1 2 5 " ]] || fail "--sweep deleted the wrong set" |
| 77 | |
| 78 | # 3. --dry-run deletes nothing but reports the same set. |
| 79 | "${script}" --dry-run --sweep > "${tmp_dir}/out" |
| 80 | [[ -z "$(deleted_ids)" ]] || fail "--dry-run deleted caches" |
| 81 | grep -q "would delete 3 caches, 1900 bytes" "${tmp_dir}/out" || fail "--dry-run summary" |
| 82 | |
| 83 | # 4. Branch refs are refused outright. |
| 84 | if "${script}" --ref refs/heads/main > "${tmp_dir}/out" 2>&1; then |
| 85 | fail "a branch ref was accepted" |
| 86 | fi |
| 87 | [[ -z "$(deleted_ids)" ]] || fail "a refused ref still deleted caches" |
| 88 | |
| 89 | # 5. A tag ref deletes only that tag. |
| 90 | "${script}" --ref refs/tags/v0.10.1 > "${tmp_dir}/out" |
| 91 | [[ "$(deleted_ids)" == "6 " ]] || fail "--ref tag deleted the wrong set" |
| 92 | |
| 93 | echo "prune-actions-caches tests passed" |
| 94 |