Skip to content

Commit 17e4eaa

Browse files
committed
ci: cache dockerized playwright npm packages
1 parent a389148 commit 17e4eaa

3 files changed

Lines changed: 70 additions & 3 deletions

File tree

.github/workflows/quality.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,19 @@ jobs:
3030
with:
3131
node-version: 24
3232

33+
- name: Restore npm cache for Dockerized Playwright
34+
id: playwright-docker-npm-cache
35+
uses: actions/cache/restore@v4
36+
continue-on-error: true
37+
with:
38+
path: .npm-cache
39+
key: ${{ runner.os }}-playwright-docker-npm-${{ hashFiles('package-lock.json') }}
40+
3341
- name: Run Playwright tests
3442
run: bash scripts/playwright-docker.sh --shard=${{ matrix.shard }}/${{ matrix.shardTotal }}
3543
env:
3644
CI: 'true'
45+
PLAYWRIGHT_NPM_CACHE_DIR: ${{ github.workspace }}/.npm-cache
3746

3847
- name: Upload blob report
3948
if: always()
@@ -43,6 +52,14 @@ jobs:
4352
path: blob-report
4453
retention-days: 1
4554

55+
- name: Save npm cache for Dockerized Playwright
56+
if: always() && matrix.shard == 1 && steps.playwright-docker-npm-cache.outputs.cache-hit != 'true'
57+
uses: actions/cache/save@v4
58+
continue-on-error: true
59+
with:
60+
path: .npm-cache
61+
key: ${{ runner.os }}-playwright-docker-npm-${{ hashFiles('package-lock.json') }}
62+
4663
merge_reports:
4764
name: Merge Playwright Reports
4865
if: always()

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
# testing
99
/coverage
1010
playwright-artifacts
11+
.npm-cache/
1112

1213
# ai-workflow
1314
plans/
@@ -36,4 +37,4 @@ yarn-error.log*
3637

3738
embedded-ui.tar.bz2
3839

39-
.codeassistant
40+
.codeassistant

scripts/playwright-docker.sh

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ DEFAULT_INTERNAL_BACKEND="http://${YDB_CONTAINER_NAME}:8765"
2626
INTERNAL_BROWSER_BACKEND="http://localhost:8765"
2727
PLAYWRIGHT_BACKEND="${EXTERNAL_BACKEND:-$INTERNAL_BROWSER_BACKEND}"
2828
PLAYWRIGHT_BASE_URL_VALUE="${PLAYWRIGHT_BASE_URL:-}"
29+
PLAYWRIGHT_NPM_CACHE_DIR_VALUE="${PLAYWRIGHT_NPM_CACHE_DIR:-}"
2930
DEFAULT_YDB_ALLOW_ORIGIN="http://localhost:3000"
3031
YDB_ALLOW_ORIGIN="${PLAYWRIGHT_YDB_ALLOW_ORIGIN:-$DEFAULT_YDB_ALLOW_ORIGIN}"
3132
YDB_PLATFORM="${PLAYWRIGHT_YDB_PLATFORM:-}"
@@ -55,6 +56,17 @@ NODE
5556
)
5657
fi
5758

59+
DOCKER_NPM_CACHE_ARGS=()
60+
DOCKER_NPM_CACHE_ENV_ARGS=()
61+
NPM_CI_COMMAND="npm ci"
62+
63+
if [ -n "$PLAYWRIGHT_NPM_CACHE_DIR_VALUE" ]; then
64+
mkdir -p "$PLAYWRIGHT_NPM_CACHE_DIR_VALUE"
65+
DOCKER_NPM_CACHE_ARGS=(-v "${PLAYWRIGHT_NPM_CACHE_DIR_VALUE}:/npm-cache")
66+
DOCKER_NPM_CACHE_ENV_ARGS=(-e NPM_CONFIG_CACHE="/npm-cache")
67+
NPM_CI_COMMAND="npm ci --prefer-offline"
68+
fi
69+
5870
cleanup() {
5971
if [ "$YDB_CONTAINER_STARTED" -eq 1 ]; then
6072
echo "Cleaning up YDB backend container ${YDB_CONTAINER_NAME}"
@@ -78,6 +90,15 @@ print_ydb_diagnostics() {
7890
docker inspect "$YDB_CONTAINER_NAME" --format 'status={{.State.Status}} running={{.State.Running}} health={{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}} exit={{.State.ExitCode}} error={{.State.Error}}' 2>/dev/null || true
7991
}
8092

93+
print_elapsed() {
94+
local label="$1"
95+
local started_at="$2"
96+
local finished_at
97+
98+
finished_at="$(date +%s)"
99+
echo "${label} completed in $((finished_at - started_at))s"
100+
}
101+
81102
wait_for_ydb() {
82103
local max_attempts=60
83104
local attempt=1
@@ -107,6 +128,15 @@ wait_for_ydb() {
107128
PLAYWRIGHT_COMMAND=$(cat <<'SCRIPT'
108129
set -euo pipefail
109130
131+
print_elapsed() {
132+
local label="$1"
133+
local started_at="$2"
134+
local finished_at
135+
136+
finished_at="$(date +%s)"
137+
echo "${label} completed in $((finished_at - started_at))s"
138+
}
139+
110140
if [ -n "${PLAYWRIGHT_YDB_PROXY_TARGET:-}" ]; then
111141
echo "Forwarding localhost:8765 to ${PLAYWRIGHT_YDB_PROXY_TARGET}"
112142
node <<'NODE' &
@@ -124,8 +154,10 @@ server.listen(8765, '127.0.0.1');
124154
NODE
125155
fi
126156
127-
echo "Running npm ci"
128-
npm ci
157+
echo "Running ${NPM_CI_COMMAND}"
158+
npm_ci_started_at="$(date +%s)"
159+
${NPM_CI_COMMAND}
160+
print_elapsed "npm install" "$npm_ci_started_at"
129161
130162
echo "Running Playwright tests"
131163
npx playwright test --config=playwright.config.ts "$@"
@@ -135,6 +167,9 @@ SCRIPT
135167
echo "Using Playwright Docker image: ${DOCKER_IMAGE}"
136168
echo "Using YDB Docker image: ${YDB_IMAGE}"
137169
echo "Docker network: ${NETWORK_NAME}"
170+
if [ -n "$PLAYWRIGHT_NPM_CACHE_DIR_VALUE" ]; then
171+
echo "Using npm cache directory: ${PLAYWRIGHT_NPM_CACHE_DIR_VALUE}"
172+
fi
138173

139174
if [ "$START_INTERNAL_BACKEND" -eq 1 ]; then
140175
echo "Starting YDB backend container: ${YDB_IMAGE}"
@@ -170,6 +205,7 @@ else
170205
fi
171206

172207
echo "Installing dependencies and running Playwright tests in Docker"
208+
playwright_docker_started_at="$(date +%s)"
173209
set +e
174210
if [ -n "$PLAYWRIGHT_PLATFORM" ] && [ "$START_INTERNAL_BACKEND" -eq 1 ]; then
175211
echo "Requested Playwright platform: ${PLAYWRIGHT_PLATFORM}"
@@ -179,13 +215,16 @@ if [ -n "$PLAYWRIGHT_PLATFORM" ] && [ "$START_INTERNAL_BACKEND" -eq 1 ]; then
179215
--add-host host.docker.internal:host-gateway \
180216
-v "${PROJECT_DIR}:/work" \
181217
-v "ydb-embedded-ui-node-modules:/work/node_modules" \
218+
"${DOCKER_NPM_CACHE_ARGS[@]}" \
182219
-w /work \
183220
-e CI="${CI:-}" \
184221
-e PLAYWRIGHT_VIDEO="${PLAYWRIGHT_VIDEO:-}" \
185222
-e PLAYWRIGHT_APP_BACKEND="${PLAYWRIGHT_BACKEND}" \
186223
-e PLAYWRIGHT_BASE_URL="${PLAYWRIGHT_BASE_URL_VALUE}" \
187224
-e PLAYWRIGHT_OUTPUT_DIR="${PLAYWRIGHT_OUTPUT_DIR}" \
188225
-e PLAYWRIGHT_YDB_PROXY_TARGET="${YDB_PROXY_TARGET}" \
226+
-e NPM_CI_COMMAND="${NPM_CI_COMMAND}" \
227+
"${DOCKER_NPM_CACHE_ENV_ARGS[@]}" \
189228
"${DOCKER_IMAGE}" \
190229
/bin/bash -c "$PLAYWRIGHT_COMMAND" -- "$@"
191230
elif [ -n "$PLAYWRIGHT_PLATFORM" ]; then
@@ -195,13 +234,16 @@ elif [ -n "$PLAYWRIGHT_PLATFORM" ]; then
195234
--add-host host.docker.internal:host-gateway \
196235
-v "${PROJECT_DIR}:/work" \
197236
-v "ydb-embedded-ui-node-modules:/work/node_modules" \
237+
"${DOCKER_NPM_CACHE_ARGS[@]}" \
198238
-w /work \
199239
-e CI="${CI:-}" \
200240
-e PLAYWRIGHT_VIDEO="${PLAYWRIGHT_VIDEO:-}" \
201241
-e PLAYWRIGHT_APP_BACKEND="${PLAYWRIGHT_BACKEND}" \
202242
-e PLAYWRIGHT_BASE_URL="${PLAYWRIGHT_BASE_URL_VALUE}" \
203243
-e PLAYWRIGHT_OUTPUT_DIR="${PLAYWRIGHT_OUTPUT_DIR}" \
204244
-e PLAYWRIGHT_YDB_PROXY_TARGET="${YDB_PROXY_TARGET}" \
245+
-e NPM_CI_COMMAND="${NPM_CI_COMMAND}" \
246+
"${DOCKER_NPM_CACHE_ENV_ARGS[@]}" \
205247
"${DOCKER_IMAGE}" \
206248
/bin/bash -c "$PLAYWRIGHT_COMMAND" -- "$@"
207249
elif [ "$START_INTERNAL_BACKEND" -eq 1 ]; then
@@ -210,32 +252,39 @@ elif [ "$START_INTERNAL_BACKEND" -eq 1 ]; then
210252
--add-host host.docker.internal:host-gateway \
211253
-v "${PROJECT_DIR}:/work" \
212254
-v "ydb-embedded-ui-node-modules:/work/node_modules" \
255+
"${DOCKER_NPM_CACHE_ARGS[@]}" \
213256
-w /work \
214257
-e CI="${CI:-}" \
215258
-e PLAYWRIGHT_VIDEO="${PLAYWRIGHT_VIDEO:-}" \
216259
-e PLAYWRIGHT_APP_BACKEND="${PLAYWRIGHT_BACKEND}" \
217260
-e PLAYWRIGHT_BASE_URL="${PLAYWRIGHT_BASE_URL_VALUE}" \
218261
-e PLAYWRIGHT_OUTPUT_DIR="${PLAYWRIGHT_OUTPUT_DIR}" \
219262
-e PLAYWRIGHT_YDB_PROXY_TARGET="${YDB_PROXY_TARGET}" \
263+
-e NPM_CI_COMMAND="${NPM_CI_COMMAND}" \
264+
"${DOCKER_NPM_CACHE_ENV_ARGS[@]}" \
220265
"${DOCKER_IMAGE}" \
221266
/bin/bash -c "$PLAYWRIGHT_COMMAND" -- "$@"
222267
else
223268
docker run --rm \
224269
--add-host host.docker.internal:host-gateway \
225270
-v "${PROJECT_DIR}:/work" \
226271
-v "ydb-embedded-ui-node-modules:/work/node_modules" \
272+
"${DOCKER_NPM_CACHE_ARGS[@]}" \
227273
-w /work \
228274
-e CI="${CI:-}" \
229275
-e PLAYWRIGHT_VIDEO="${PLAYWRIGHT_VIDEO:-}" \
230276
-e PLAYWRIGHT_APP_BACKEND="${PLAYWRIGHT_BACKEND}" \
231277
-e PLAYWRIGHT_BASE_URL="${PLAYWRIGHT_BASE_URL_VALUE}" \
232278
-e PLAYWRIGHT_OUTPUT_DIR="${PLAYWRIGHT_OUTPUT_DIR}" \
233279
-e PLAYWRIGHT_YDB_PROXY_TARGET="${YDB_PROXY_TARGET}" \
280+
-e NPM_CI_COMMAND="${NPM_CI_COMMAND}" \
281+
"${DOCKER_NPM_CACHE_ENV_ARGS[@]}" \
234282
"${DOCKER_IMAGE}" \
235283
/bin/bash -c "$PLAYWRIGHT_COMMAND" -- "$@"
236284
fi
237285
TEST_EXIT_CODE=$?
238286
set -e
287+
print_elapsed "Dockerized Playwright run" "$playwright_docker_started_at"
239288

240289
if [ -n "$SHOULD_SHOW_REPORT" ]; then
241290
if [ ! -d "$REPORT_DIR" ]; then

0 commit comments

Comments
 (0)