Skip to content

Commit d6a376c

Browse files
kanadguptaclaude
andauthored
ci(cli): cache only the pnpm content store, not the virtual store (#6471)
## Summary Since #6424 enabled `virtualStoreType: global`, `pnpm store path` includes `links/`, the global virtual store. It is a tree of directory links between packages: symlinks on POSIX, NTFS junctions on Windows. The shared setup action cached that whole directory, and on Windows the junctions do not survive the actions/cache tar round trip as traversable directories. pnpm then trusts every restored `links/` directory as complete and skips relinking, so the first dependency resolved through a restored junction fails. That is the `DiscoveryError: Unable to resolve @typescript/typescript-win32-x64` from the root `prepare` script in [this release run](https://github.com/supabase/cli/actions/runs/33854068778/job/100967241418). The failure was deterministic, not transient: every Windows release smoke-test with a pnpm-store cache hit failed, and the only success with the new store layout was the cache-miss run that populated the cache. The earlier Windows failures that week were the unrelated CRLF patch-file problem fixed in #6461. ## Changes - Cache only `files/` and the SQLite index of the pnpm store, never `links/`. pnpm rebuilds the virtual store from the cached files with hardlinks and no network. The first Linux jobs after #6424 already demonstrated this path when they restored an older files-only archive via `restore-keys`. - Bump the cache key prefix to `pnpm-store-files-…`. actions/cache restores whatever an archive contains regardless of the current `path` input, so without the bump Windows would keep restoring the existing archive that carries `links/` until the lockfile changed. - Remove the Windows-only cache exclusion from #6464, restoring dependency caching on the Windows release jobs. ## Reviewer context The release workflow only runs on `develop`, so PR CI exercises the new caching on Linux but not the Windows smoke-test job. The first run on each OS will be a cache miss under the new prefix. The second Windows release run after merge is the real confirmation, since it is the first cache hit. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
1 parent adc1dfa commit d6a376c

1 file changed

Lines changed: 19 additions & 6 deletions

File tree

.github/actions/setup/action.yml

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,34 @@ runs:
2323
with:
2424
version: 2026.9.0
2525

26-
# actions/cache-restored pnpm global virtual-store links are unusable on Windows; fresh installs reconstruct them.
2726
- name: Resolve pnpm store path
28-
if: inputs.dependency-cache == 'true' && runner.os != 'Windows'
27+
if: inputs.dependency-cache == 'true'
2928
id: pnpm-store
3029
shell: bash
3130
run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
3231

32+
# Cache only the content-addressable half of the store (package files plus
33+
# the SQLite index), never the global virtual store under links/. That
34+
# directory is a web of directory links between packages: symlinks on
35+
# POSIX, NTFS junctions on Windows. actions/cache round-trips it through
36+
# tar, and on Windows the junctions do not come back as traversable
37+
# directories. pnpm then trusts every restored links/ directory as complete
38+
# and skips relinking, so the first dependency resolved through a restored
39+
# junction fails (release smoke-test, Sept 2026). Rebuilding links/ from the
40+
# cached files is hardlink-only and needs no network, and pnpm itself notes
41+
# the global virtual store has little value in CI. The key prefix is bumped
42+
# so restores never match the earlier whole-store archives, which still
43+
# carry a links/ tree.
3344
- name: Configure pnpm dependency cache
34-
if: inputs.dependency-cache == 'true' && runner.os != 'Windows'
45+
if: inputs.dependency-cache == 'true'
3546
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
3647
with:
37-
path: ${{ steps.pnpm-store.outputs.path }}
38-
key: pnpm-store-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('pnpm-lock.yaml') }}
48+
path: |
49+
${{ steps.pnpm-store.outputs.path }}/files
50+
${{ steps.pnpm-store.outputs.path }}/index*
51+
key: pnpm-store-files-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('pnpm-lock.yaml') }}
3952
restore-keys: |
40-
pnpm-store-${{ runner.os }}-${{ runner.arch }}-
53+
pnpm-store-files-${{ runner.os }}-${{ runner.arch }}-
4154
4255
- name: Resolve Go cache paths
4356
if: inputs.dependency-cache == 'true'

0 commit comments

Comments
 (0)