Skip to content

chore(ci): reduce cache bloat by saving only on main#8204

Merged
steveruizok merged 2 commits intomainfrom
fix/ci-cache-bloat
Mar 11, 2026
Merged

chore(ci): reduce cache bloat by saving only on main#8204
steveruizok merged 2 commits intomainfrom
fix/ci-cache-bloat

Conversation

@steveruizok
Copy link
Copy Markdown
Collaborator

@steveruizok steveruizok commented Mar 11, 2026

In order to reduce GitHub Actions cache storage from ~1.1GB per PR to ~300MB shared, this PR changes the setup action to cache only .yarn/cache and .yarn/install-state.gz (dropping node_modules and .yarn/unplugged), use restore-only caching on PRs via actions/cache/restore, and save the cache only on pushes to main via actions/cache/save.

Relates to #7628

Change type

  • improvement

Test plan

  1. Verify CI passes on this PR (cache restore still works from main's existing entry)
  2. After merging, confirm new cache entries on main are ~300MB instead of ~1.1GB
  3. Clean up old Linux-node-24.13.1-yarn-* cache entries from the Actions cache page

Code changes

Section LOC change
Config/tooling +14 / -6

Note

Low Risk
CI-only caching behavior change; main risk is slower installs or cache misses if keys/paths are misconfigured, with no production/runtime impact.

Overview
The CI setup composite action switches from caching node_modules to caching only Yarn’s .yarn/cache and .yarn/install-state.gz, reducing cache size and avoiding per-branch duplication.

It now uses actions/cache/restore@v5 to restore caches for all runs, and conditionally saves the cache via actions/cache/save@v5 only on push events to refs/heads/main (and only when the restore wasn’t a hit).

Written by Cursor Bugbot for commit 45d8053. This will update automatically on new commits. Configure here.

Previously every PR saved its own ~1.1GB cache entry containing all
node_modules directories. Now we:
- Cache only .yarn/cache and install-state.gz (~200-400MB)
- Use restore-only on PRs (actions/cache/restore)
- Save only on pushes to main (actions/cache/save)

PRs still restore from main's cache; yarn install reconstructs
node_modules from the offline cache with minimal overhead.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 11, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
examples Ready Ready Preview Mar 11, 2026 3:34pm
5 Skipped Deployments
Project Deployment Actions Updated (UTC)
analytics Ignored Ignored Preview Mar 11, 2026 3:34pm
chat-template Ignored Ignored Preview Mar 11, 2026 3:34pm
tldraw-docs Ignored Ignored Preview Mar 11, 2026 3:34pm
tldraw-shader Ignored Ignored Preview Mar 11, 2026 3:34pm
workflow-template Ignored Ignored Preview Mar 11, 2026 3:34pm

Request Review

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Copy link
Copy Markdown
Member

@mimecuvalo mimecuvalo left a comment

Choose a reason for hiding this comment

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

👍

# Only save the cache on pushes to main to avoid per-PR duplicates.
# Runs after install so the cache is fully populated.
- name: Save yarn cache
if: github.event_name == 'push' && steps.yarn-cache.outputs.cache-hit != 'true'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What the claude suggests is: if: github.event_name == 'push' && github.ref == 'refs/heads/main' && steps.yarn-cache.outputs.cache-hit != 'true'

@steveruizok steveruizok changed the title Reduce CI cache bloat from ~1.1GB per PR to ~300MB shared chore(ci): reduce cache bloat by saving only on main Mar 11, 2026
@huppy-bot huppy-bot bot added the improvement Product improvement label Mar 11, 2026
Add github.ref check so cache is only saved on pushes to main,
not production/bemo-production branches.
Copy link
Copy Markdown
Contributor

@kaneel kaneel left a comment

Choose a reason for hiding this comment

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

LGTM

@steveruizok steveruizok added this pull request to the merge queue Mar 11, 2026
Merged via the queue into main with commit c4df25a Mar 11, 2026
22 checks passed
@steveruizok steveruizok deleted the fix/ci-cache-bloat branch March 11, 2026 16:18
mimecuvalo added a commit that referenced this pull request Mar 24, 2026
github-merge-queue bot pushed a commit that referenced this pull request Mar 24, 2026
…eous cache generation (#8333)

Couple things going on here to unpack:
- this reverts #8204
- b/c that was reverted our CI times went from 4/5 min back to 8min
because we had to recompile things during setup.yml in the `yarn` step.
this was adding ~2min back to each CI action.
- we were hitting our 10GB limit before but the majority of that was
because we were adding `-${{github.sha}}` to a bunch of our tooling
caches, creating a bunch of extra cache entries for no reason

Fixes:
- removes the `${{github.sha}}` from the key, unnecessary.
- caches `node_modules` again to save CI time again
- I increased our org cache limit to 20GB for now, we only pay for
actual usage, things get auto-purged after 7 days anyway
<img width="476" height="137" alt="Screenshot 2026-03-24 at 14 26 19"
src="https://github.com/user-attachments/assets/8ddfa763-554a-4270-a832-69628f23fa6f"
/>

- i'll manually clear some cache entries as well
github-merge-queue bot pushed a commit that referenced this pull request Mar 25, 2026
#8276)

In order to stop docs-only hotfixes from triggering unwanted npm patch
releases, this PR adds `yarn refresh-assets --force` before the
`getAnyPackageDiff()` check in `publish-patch.ts`.

### Root cause

PR #8204 added `.yarn/install-state.gz` to the CI cache. When Yarn
determines that the install state hasn't changed (e.g. `node_modules` is
already populated and no dependencies changed), it [skips lifecycle
scripts](https://yarnpkg.com/advanced/lifecycle-scripts) including
`postinstall` ([related
discussion](yarnpkg/berry#5924)). This
means the `postinstall` hook (`husky install && yarn refresh-assets`)
never runs.

Without `refresh-assets`, the gitignored asset directories in
`@tldraw/assets` (`embed-icons/`, `fonts/`, `icons/`, `translations/`)
don't exist on disk. The `getAnyPackageDiff()` guard runs `yarn pack`
which produces a tarball missing these dirs (14 files), while the
npm-published tarball has them (265 files) — always finding a diff,
always publishing.

**Before #8204 (working):** PR #8102 docs hotfix cherry-picked to v4.4.x
— publish-patch skipped correctly, no version bump.

**After #8204 (broken):** PRs #8263 and #8270 docs hotfixes
cherry-picked to v4.5.x — both triggered unwanted npm publishes (v4.5.1
and v4.5.2).

### Why this approach

Considered three options:
1. **Remove `install-state.gz` from cache** — doesn't actually help;
Yarn skips postinstall based on dependency changes, not just the state
file
2. **Add `refresh-assets` to the setup action** — overkill; lazyrepo
already auto-runs it as a dependency of `build`, `build-types`, and
`dev`
3. **Add `refresh-assets` to `publish-patch.ts`** — targeted fix
matching what `trigger-sdk-hotfix.ts` already does (line 98)

Option 3 is the right call. `publish-patch.ts` is the only workflow
confirmed broken — everything else is protected by either lazyrepo's
dependency graph or explicit `refresh-assets` calls in the workflow
YAML.

### Change type

- [x] `bugfix`

### Test plan

Verified locally:
1. Removed asset dirs to simulate CI with warm cache (no postinstall)
2. `yarn pack` on `@tldraw/assets` → 14 files
3. Ran `yarn refresh-assets --force`
4. `yarn pack` again → 265 files

On a release branch with only docs changes, `getAnyPackageDiff()` should
now return `null` → "No packages have changed, skipping release" → no
publish.

### Code changes

| Section        | LOC change |
| -------------- | ---------- |
| Config/tooling | +4 / -0    |
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Product improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants