Skip to content

Commit 82947fa

Browse files
fix: improve CI caching strategy to avoid pnpm hard link errors
- Cache only pnpm store directory instead of node_modules - Separate caches for pnpm store, Cypress binary, and Playwright browsers - Fix hard link errors by letting pnpm recreate node_modules from cached store - Update both pull request and push workflows with consistent caching - Remove unused env variables CACHE_PATH and YARN_CACHE_PATH - Add conditional installation for Cypress and Playwright based on cache hits This resolves the '/node_modules/.bin: Cannot hard link' errors and improves CI performance by reducing cache size and avoiding symlink issues.
1 parent e7b0fb5 commit 82947fa

File tree

2 files changed

+102
-45
lines changed

2 files changed

+102
-45
lines changed

.github/workflows/on-pull-request.yml

Lines changed: 68 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,6 @@ concurrency:
66
cancel-in-progress: true
77

88
env:
9-
CACHE_PATH: |
10-
**/node_modules
11-
~/.cache/Cypress
12-
YARN_CACHE_PATH: |
13-
~/.pnpm-store
149
FILES_TO_DELETE: |
1510
sudo rm -rf "/usr/share/dotnet"
1611
sudo rm -rf "/usr/share/swift"
@@ -130,14 +125,26 @@ jobs:
130125
- name: Setup pnpm cache
131126
uses: actions/cache@v4
132127
with:
133-
path: |
134-
${{ steps.pnpm-cache.outputs.STORE_PATH }}
135-
**/node_modules
136-
~/.cache/Cypress
137-
~/.cache/ms-playwright
138-
key: deps-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
128+
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
129+
key: pnpm-store-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
139130
restore-keys: |
140-
deps-${{ runner.os }}-
131+
pnpm-store-${{ runner.os }}-
132+
133+
- name: Cache Cypress binary
134+
uses: actions/cache@v4
135+
with:
136+
path: ~/.cache/Cypress
137+
key: cypress-${{ runner.os }}-cypress-13.12.0
138+
restore-keys: |
139+
cypress-${{ runner.os }}-
140+
141+
- name: Cache Playwright browsers
142+
uses: actions/cache@v4
143+
with:
144+
path: ~/.cache/ms-playwright
145+
key: playwright-${{ runner.os }}-1.54.2
146+
restore-keys: |
147+
playwright-${{ runner.os }}-
141148
142149
- name: Install dependencies
143150
run: |
@@ -191,37 +198,70 @@ jobs:
191198
run: |
192199
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
193200
194-
- name: Restore dependency cache
201+
- name: Restore pnpm cache
195202
uses: actions/cache/restore@v4
196-
id: deps-cache
197-
with:
198-
path: |
199-
${{ steps.pnpm-cache.outputs.STORE_PATH }}
200-
**/node_modules
201-
~/.cache/Cypress
202-
~/.cache/ms-playwright
203-
key: deps-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
203+
id: pnpm-store-cache
204+
with:
205+
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
206+
key: pnpm-store-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
204207
restore-keys: |
205-
deps-${{ runner.os }}-
208+
pnpm-store-${{ runner.os }}-
206209
fail-on-cache-miss: false
207210

208-
- name: Install deps if cache miss
211+
- name: Restore Cypress cache
212+
uses: actions/cache/restore@v4
213+
id: cypress-cache
214+
with:
215+
path: ~/.cache/Cypress
216+
key: cypress-${{ runner.os }}-cypress-13.12.0
217+
restore-keys: |
218+
cypress-${{ runner.os }}-
219+
fail-on-cache-miss: false
220+
221+
- name: Restore Playwright cache
222+
if: matrix.container == 'bi-directional'
223+
uses: actions/cache/restore@v4
224+
id: playwright-cache
225+
with:
226+
path: ~/.cache/ms-playwright
227+
key: playwright-${{ runner.os }}-1.54.2
228+
restore-keys: |
229+
playwright-${{ runner.os }}-
230+
fail-on-cache-miss: false
231+
232+
- name: Install dependencies
209233
id: install-deps-e2e
210-
if: steps.deps-cache.outputs.cache-hit != 'true'
211234
env:
212235
NODE_OPTIONS: '--max_old_space_size=6144'
213236
FORCE_COLOR: 3
214237
run: |
215-
echo "Cache miss - this should not happen as deps were installed in setup-matrix job"
238+
echo "Installing dependencies from cached pnpm store..."
216239
pnpm install --frozen-lockfile --prefer-offline
217-
npx cypress verify
240+
241+
# Verify Cypress if needed
242+
if [ "${{ steps.cypress-cache.outputs.cache-hit }}" != "true" ]; then
243+
echo "Installing Cypress binary..."
244+
npx cypress install
245+
else
246+
echo "Cypress binary already cached"
247+
npx cypress verify || true
248+
fi
218249
219250
- name: Install Playwright for projects that need it
220251
run: |
221252
if [ "${{ matrix.container }}" = "bi-directional" ]; then
222-
echo "Installing Playwright for bi-directional example..."
253+
echo "Setting up Playwright for bi-directional example..."
223254
cd ${{ matrix.container }}
224-
npx playwright install --with-deps chromium
255+
256+
# Check if Playwright browsers are already cached
257+
if [ "${{ steps.playwright-cache.outputs.cache-hit }}" = "true" ] && [ -d "$HOME/.cache/ms-playwright" ]; then
258+
echo "Playwright browsers already cached, installing system dependencies only..."
259+
npx playwright install-deps chromium
260+
else
261+
echo "Installing Playwright browsers and dependencies..."
262+
npx playwright install --with-deps chromium
263+
fi
264+
225265
cd ..
226266
fi
227267

.github/workflows/on-push.yml

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ concurrency:
99
cancel-in-progress: true
1010

1111
env:
12-
CACHE_PATH: |
13-
**/node_modules
14-
~/.cache/Cypress
15-
~/.pnpm-store
1612
FILES_TO_DELETE: |
1713
sudo rm -rf "/usr/share/dotnet"
1814
sudo rm -rf "/usr/share/swift"
@@ -75,26 +71,47 @@ jobs:
7571
cache: 'pnpm'
7672
cache-dependency-path: '**/pnpm-lock.yaml'
7773

78-
- name: Enhanced caching with fallbacks
74+
- name: Get pnpm store directory
75+
id: pnpm-cache
76+
shell: bash
77+
run: |
78+
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
79+
80+
- name: Setup pnpm cache
81+
uses: actions/cache@v4
82+
id: pnpm-store-cache
83+
with:
84+
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
85+
key: pnpm-store-${{ runner.os }}-${{ steps.yarn-hash.outputs.yarnHash }}
86+
restore-keys: |
87+
pnpm-store-${{ runner.os }}-
88+
89+
- name: Cache Cypress binary
90+
uses: actions/cache@v4
91+
with:
92+
path: ~/.cache/Cypress
93+
key: cypress-${{ runner.os }}-cypress-13.12.0
94+
restore-keys: |
95+
cypress-${{ runner.os }}-
96+
97+
- name: Cache Playwright browsers
7998
uses: actions/cache@v4
80-
id: yarn-cache
8199
with:
82-
path: |
83-
~/.pnpm-store
84-
**/node_modules
85-
~/.cache/Cypress
86-
~/.cache/ms-playwright
87-
key: e2e-cache-${{ runner.os }}-${{ steps.yarn-hash.outputs.yarnHash }}
100+
path: ~/.cache/ms-playwright
101+
key: playwright-${{ runner.os }}-1.54.2
88102
restore-keys: |
89-
e2e-cache-${{ runner.os }}-
90-
e2e-cache-
103+
playwright-${{ runner.os }}-
91104
92105
- name: Install deps
93-
if: steps.yarn-cache.outputs.cache-hit != 'true'
94106
env:
95107
NODE_OPTIONS: '--max_old_space_size=6144'
96108
FORCE_COLOR: 3
97109
run: |
98-
echo "PNPM lockfile changed - installing dependencies..."
99-
pnpm config set store-dir ~/.pnpm-store
110+
echo "Installing dependencies from pnpm store..."
100111
pnpm install --frozen-lockfile --prefer-offline
112+
113+
# Install Cypress binary if not cached
114+
if [ -z "$(ls -A ~/.cache/Cypress 2>/dev/null)" ]; then
115+
echo "Installing Cypress binary..."
116+
npx cypress install
117+
fi

0 commit comments

Comments
 (0)