summaryrefslogtreecommitdiffstats
path: root/.github/workflows
diff options
context:
space:
mode:
authorKacper Michajłow <kasper93@gmail.com>2024-05-19 02:05:21 +0200
committerKacper Michajłow <kasper93@gmail.com>2024-05-19 20:35:34 +0200
commitc6b950ae1e722dbe8c2414017a3c521f8c5730e9 (patch)
tree7485ec1262c585bc68c427e96dc1d1f88024e337 /.github/workflows
parenta16f653eb56a80d55448ad915b3e0df325bb2c31 (diff)
downloadmpv-c6b950ae1e722dbe8c2414017a3c521f8c5730e9.tar.bz2
mpv-c6b950ae1e722dbe8c2414017a3c521f8c5730e9.tar.xz
ci: clear old caches to avoid master branch cache trashing
GitHub cache action doesn't allow updating cache with the same key. We workaround this by saving the cache with a unique key each time (added timestamp). This works fine, but since there is a limit on cumulative storage size for all caches, it can force the master branch cache to be evicted if a lot of PRs are updated. Cache is evicted with LRU policy, so as long as master branch cache is used it should stay alive, but it can happen that only PR specifc caches were only used. As a reminder, PRs can access the master cache, but they are isolated from each other. Because of this, it is important to keep the master cache, which is available to all, alive longer. The solution is to remove all old caches per branch. This is done in a separate workflow that validates all cache items and removes ones that would never be used anyway. If PR is closed all caches per branch are removed. In other cases most recently used one is preserved. It is done in a separate workflow to limit cache manipulation access. GitHub workflows triggered by pull_request event are run in the context of the fork and does not have access to our token, which is good thing. Also it is quite awkward to get PR number which triggered build workflow, so just do a full cleanup pass.
Diffstat (limited to '.github/workflows')
-rw-r--r--.github/workflows/cleanup_caches.yml37
1 files changed, 37 insertions, 0 deletions
diff --git a/.github/workflows/cleanup_caches.yml b/.github/workflows/cleanup_caches.yml
new file mode 100644
index 0000000000..fdc692682e
--- /dev/null
+++ b/.github/workflows/cleanup_caches.yml
@@ -0,0 +1,37 @@
+name: Cleanup caches
+
+on:
+ workflow_run:
+ workflows: [build]
+ types: [completed]
+
+jobs:
+ cache:
+ runs-on: ubuntu-latest
+ steps:
+ - run: |
+ caches=$(gh cache list -R ${{ github.repository }} -L 100 --json id,key,ref -S last_accessed_at -O desc)
+ echo "$caches" | jq -c '
+ map(select(.key | startswith("x86_64-w64-mingw32-") or
+ startswith("i686-w64-mingw32-") or
+ startswith("x86_64-windows-msvc-"))) |
+ group_by(.ref) |
+ map({
+ ref: .[0].ref,
+ caches: map(.key)
+ }) |
+ .[]
+ ' |
+ while read -r group; do
+ pr=$(echo "$group" | jq -r '.ref | capture("refs/pull/(?<num>[0-9]+)/merge").num')
+ if [[ -n "$pr" ]] && [ "$(gh pr view -R ${{ github.repository }} $pr --json state --jq '.state')" != "OPEN" ]; then
+ keys=$(echo "$group" | jq -c '.caches')
+ else
+ keys=$(echo "$group" | jq -c '.caches[1:]')
+ fi
+ for key in $(echo "$keys" | jq -r '.[]'); do
+ gh cache delete "$key" -R ${{ github.repository }}
+ done
+ done
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}