Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/ci-cache-cleanup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: CI Cache Cleanup

# test-build.yml keys the Next.js build cache sticky disk per branch, so every PR
# leaves a ~5 GB volume behind. Branches are short-lived; the disks aren't. Only
# the pull_request disks are reclaimed — the push disks belong to main/staging/dev
# and must stay warm.

on:
pull_request:
types: [closed]

permissions:
contents: read

jobs:
delete-nextjs-cache:
name: Delete Next.js build cache disk
# Sticky disks only exist on Blacksmith; the GitHub break-glass path uses
# actions/cache, which expires on its own.
if: vars.CI_PROVIDER == '' || vars.CI_PROVIDER == 'blacksmith'
runs-on: blacksmith-2vcpu-ubuntu-2404
timeout-minutes: 5

steps:
# Must stay byte-identical to the Mount Next.js build cache key in
# test-build.yml, or this deletes nothing and the disks accumulate.
# Non-blocking: PRs skipped by ci.yml's paths-ignore never made a disk.
- name: Delete sticky disk
uses: useblacksmith/stickydisk-delete@b41313d28b8647d72114c9ba3c96bb04061562b6 # v1
continue-on-error: true
with:
delete-key: ${{ github.repository }}-nextjs-cache-pull_request${{ github.event.pull_request.head.repo.fork && '-fork' || '' }}-${{ github.head_ref }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fork cleanup key can miss

Low Severity

The delete key relies on github.event.pull_request.head.repo.fork, but on pull_request closed that head.repo can be null when the source fork was deleted. The expression then omits the -fork suffix, so cleanup targets a different key than the mount used and the ~5 GB disk is left behind. continue-on-error hides the failed delete.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit cb77e1e. Configure here.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sibling PR disk wiped early

Medium Severity

Cleanup deletes the Next.js sticky disk by head_ref on every PR close, but the mount key is also only head_ref-scoped. Closing one PR from a branch that still has another open PR (for example into main and staging, or a non-CI base) removes the shared volume the surviving PR still uses. The next build goes cold, and continue-on-error hides a wrong delete.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit cb77e1e. Configure here.

32 changes: 26 additions & 6 deletions .github/workflows/test-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -265,14 +265,21 @@ jobs:

# Turbopack's persistent build cache (NEXT_TURBOPACK_BUILD_CACHE below)
# writes ~5 GB into .next/cache — a sticky disk mounts it in ~1s where an
# actions/cache round-trip would eat the warm-build win. Same event/fork
# namespacing as the other mounts; the GitHub fallback inside cache-mount
# still uses actions/cache with a run_id-suffixed key.
# actions/cache round-trip would eat the warm-build win.
#
# Keyed per branch, not just per event. A sticky disk is one mutable volume
# per key: mounting clones the last committed snapshot, job end commits back
# last-write-wins. An event-only key had every open PR restoring a cache
# built from a different branch — 14.0 min vs 9.3 min for the single-writer
# push disk on the same commit. Branch scoping also keeps us off
# cross-commit restore, which turbopackFileSystemCacheForBuild (beta) does
# not document as supported (vercel/next.js#87283: stale HTML from a cache
# built at another commit). ci-cache-cleanup.yml reclaims the disks.
- name: Mount Next.js build cache
uses: ./.github/actions/cache-mount
with:
provider: ${{ vars.CI_PROVIDER }}
key: ${{ github.repository }}-nextjs-cache-${{ github.event_name }}${{ github.event.pull_request.head.repo.fork && '-fork' || '' }}
key: ${{ github.repository }}-nextjs-cache-${{ github.event_name }}${{ github.event.pull_request.head.repo.fork && '-fork' || '' }}-${{ github.head_ref || github.ref_name }}
path: ./apps/sim/.next/cache

# Running out of RAM kills the whole VM and surfaces only as "the runner
Expand All @@ -293,6 +300,13 @@ jobs:
- name: Install dependencies
run: bun install --frozen-lockfile --ignore-scripts

# The disk mounts successfully whether or not it carried anything and turbo
# buffers the build log, so cache warmth is otherwise unobservable — #5859
# shipped a cache that carried almost nothing and it took a PR to notice.
# Reported, never gated.
- name: Report Next.js cache size (pre-build)
run: du -sh apps/sim/.next/cache 2>/dev/null || echo 'cold — no cache restored'

- name: Build application
env:
NODE_OPTIONS: '--no-warnings --max-old-space-size=8192'
Expand All @@ -304,7 +318,13 @@ jobs:
AWS_REGION: 'us-west-2'
ENCRYPTION_KEY: '7cf672e460e430c1fba707575c2b0e2ad5a99dddf9b7b7e3b5646e630861db1c' # dummy key for CI only
TURBO_CACHE_DIR: .turbo
# Opt into Turbopack's persistent build cache (beta) for this CI
# check build only — measured 105s cold vs 22s warm locally.
# Opt into Turbopack's persistent build cache (beta) for this CI check
# build only. #5869's 105s-cold/22s-warm was measured locally and has
# never reproduced in CI (compile has ranged 3.5-17.8 min) — local
# numbers, not a CI target.
NEXT_TURBOPACK_BUILD_CACHE: '1'
run: bunx turbo run build --filter=sim

- name: Report Next.js cache size (post-build)
if: always()
run: du -sh apps/sim/.next/cache 2>/dev/null || echo 'no cache written'
Loading