Hit the 0.5 GB Actions storage quota today. Two-pronged fix.
1. docker-publish.yml: cache-to switched from mode=max to mode=min.
With mode=max, buildx pushes every intermediate layer of the
multi-stage build (qemu-provider, espidf-builder, frontend-builder,
final stage) into the GHA cache. For our image that's easily
500 MB-1 GB per cache update. mode=min stores only the layers used
by the final image; incremental rebuilds still hit the cache for
the meaningful steps but the footprint drops by roughly 60-70%.
2. actions-cache-cleanup.yml (new workflow):
- Weekly schedule (Sun 04:00 UTC): deletes every cache older than
14 days. Catches stale entries from deleted branches.
- On `pull_request: closed`: deletes caches scoped to that PR's
branch ref AND the merge ref. Buildx + actions/cache scope per
branch, so a closed PR's caches are immediately stale — without
this they linger until the GHA-default 7-day eviction.
- Manual `workflow_dispatch` for one-shot runs when storage is
already over.
Permissions: each job sets `actions: write` (the minimum needed for
cache deletion). No GH_TOKEN secret required; the default
GITHUB_TOKEN already has the scope.
Quota math after this lands:
Before: every push to master = +500 MB-1 GB cache, kept 7 days
→ quota fills in 1-2 builds.
After: every push to master = +200-400 MB cache, plus old branches
actively swept; 0.5 GB stays comfortable.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>