Glevkovich/ccache test #1
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Cache reaper - keeps the repo's 10 GB Actions cache budget tight. Two triggers: | |
| # - closed pull_request: delete ALL ccache entries for that PR (refs/pull/<N>/merge). | |
| # - schedule / manual: remove duplications (dedup) - keep the newest cache per (ref, config), delete older copies. | |
| # This trims refs/heads/main duplicates left by the 3-hourly regression/ | |
| # epoll runs, whose append-timestamp saves a new entry every run. | |
| name: Cache reaper | |
| on: | |
| pull_request: | |
| types: [closed] | |
| schedule: | |
| - cron: "0 */3 * * *" | |
| workflow_dispatch: | |
| # One reap per PR; scheduled/manual reaps share a single group. A newer run supersedes an in-flight one. | |
| concurrency: | |
| group: cache-reaper-${{ github.event.pull_request.number || 'scheduled' }} | |
| cancel-in-progress: true | |
| jobs: | |
| reap: | |
| # TEMPORARY: allow fork validation; remove glevkovich/dragonfly before the real PR. | |
| # Make sure that: 1) per-PR cleanups are parallel and isolated 2) scheduled dedups are serialized to one at a time. | |
| if: (github.repository == 'dragonflydb/dragonfly' || github.repository == 'glevkovich/dragonfly') && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| actions: write # required to delete caches | |
| steps: | |
| - name: Reap caches | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GH_REPO: ${{ github.repository }} | |
| PR_REF: refs/pull/${{ github.event.pull_request.number }}/merge | |
| run: | | |
| set -euo pipefail | |
| # Repo-wide cache usage (10 GB limit), printed before/after so the log shows what was reclaimed. | |
| print_repo_cache_usage() { | |
| gh api "repos/$GH_REPO/actions/cache/usage" --jq \ | |
| '"Repo cache: \(.active_caches_size_in_bytes/1048576|floor) MB used, " | |
| + "\(.active_caches_count) caches " | |
| + "(limit 10240 MB, \((10737418240 - .active_caches_size_in_bytes)/1048576|floor) MB free)"' | |
| } | |
| echo "== Before cleanup ==" | |
| print_repo_cache_usage || true | |
| if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then | |
| # PR closed/merged: delete every cache scoped to this PR ref in one non-interactive call. | |
| echo "PR closed - deleting all caches for $PR_REF" | |
| if ! gh cache delete --all --ref "$PR_REF" --succeed-on-no-caches; then | |
| echo "::warning::Some caches for $PR_REF may not have been deleted; 7-day/LRU will reclaim leftovers." | |
| fi | |
| else | |
| # Scheduled/manual: keep the newest cache per (ref, config), delete the older duplicate copies. | |
| echo "Scheduled dedup - keeping newest per (ref, config), deleting older copies" | |
| stale=$(gh cache list --limit 1000 --json id,key,ref,createdAt \ | |
| --jq '[ .[] | select(.key|test("dfly-ccache")) ] | |
| | group_by(.ref + "|" + (.key | sub("-[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9:.]+Z$";""))) | |
| | map(sort_by(.createdAt) | .[:-1]) | flatten | |
| | .[] | "\(.id)\t\(.ref)\t\(.key)"') | |
| if [ -z "$stale" ]; then | |
| echo "No stale duplicate caches." | |
| else | |
| while IFS=$'\t' read -r id ref key; do | |
| [ -n "$id" ] || continue | |
| echo "Deleting stale cache: $key (ref=$ref, id=$id)" | |
| gh cache delete "$id" || echo "::warning::failed to delete id=$id" | |
| done <<< "$stale" | |
| fi | |
| fi | |
| echo "== After cleanup ==" | |
| print_repo_cache_usage || true |