feat: persist per-runner cache volumes with surgical prune - #6
Merged
Conversation
Bun is not in this image — setup-bun installs it per job — but /root/.bun/install/cache survives between jobs in the same container. A job killed mid-download leaves a partial tarball, and every later job on that container then fails with: error: Fail extracting tarball for "next" The failure is sticky and misleading: re-running does not clear it, and it reads as a dependency problem rather than a runner problem. It was previously attributed to the macOS runners specifically, and kodni.me's ci.yml still prescribes pinning to Linux as the fix — but it just reproduced on a Linux X64 beelink. The cause is the shared cache on any persistent runner, not the OS. Also prunes the npm/pnpm/yarn stores, which fail the same way. NOTE: half a fix on its own. Workflows restoring ~/.bun/install/cache via actions/cache with restore-keys can re-import a poisoned entry from the GitHub cache, which outlives this container. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Named volumes only help if cleanup keeps bun/Gradle/Cargo homes and spares RUNNER_WORKDIR; wholesale rm -rf was the wrong policy. Co-authored-by: Cursor <cursoragent@cursor.com>
This was referenced Aug 18, 2026
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rewrite — do not merge the old rm -rf
The previous commit on this branch wiped
/root/.bun/install/cache(and npm/pnpm/yarn) after every job. Combined with cleanup already deleting Gradlebuild-cache-*/transforms-*, that would have thrown away the named volumes at the end of every job.This rewrite lands the beelink layout and keeps the caches warm.
What landed
docker-compose.yml— replaces the one-service stub with the 3-runner X64 beelink compose (YAML anchor + per-runner work and cache volumes). Not a sidecompose.beelink.yml. Volumes are per runner, not shared: concurrentbun installs must not share one tree.pre-job.sh(ACTIONS_RUNNER_HOOK_JOB_STARTED) — surgical prune only: bun*.tmp/*.part, Gradlemodules-2.lock/journal-*/daemon/. Covers OOM / killed runner (JOB_COMPLETED does not run then). Does notrm -rfcache trees.cleanup.sh(ACTIONS_RUNNER_HOOK_JOB_COMPLETED)modules-2/build-cache-*/transforms-*, Cargo registry/tmpcontents except$RUNNER_WORKDIR(and$RUNNER_TEMPif under/tmp) — workdir is/tmp/runner/work, so a blanketfind /tmp -deletewas wiping the work volume_diaglogspre-job.sh, setACTIONS_RUNNER_HOOK_JOB_STARTED, keep JOB_COMPLETED cleanupGRADLE_USER_HOME/BUN_INSTALL_CACHE_DIRon these runners (setup-stacklocal-home mode)The other half
GitHub
actions/cachewithrestore-keyscan still re-import a poisoned bun tarball. That is the shared-workflow / per-repo exact-key work, not this image.Host follow-up (after merge + image publish)
On each beelink, from this compose file (existing
runner-work*volumes keep their data; new cache volumes start empty and warm on first jobs):Do not tmpfs
/tmp. Do not share one bun/gradle volume across the three containers. ARM64 / Pi: no cache volumes.