-
Notifications
You must be signed in to change notification settings - Fork 1.5k
416 lines (410 loc) · 21.6 KB
/
Copy pathpublish_and_install.yml
File metadata and controls
416 lines (410 loc) · 21.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
name: Publish & Install
on:
workflow_dispatch:
push:
branches:
- master
- minor
- major
paths:
- 'packages/**'
- 'package.json'
- 'bun.lock'
- 'bunfig.toml'
pull_request:
branches:
- master
- major
- minor
paths:
- 'packages/**'
- 'package.json'
- 'bun.lock'
- 'bunfig.toml'
defaults:
run:
shell: bash
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
# Job 1: Build all packages and publish to Verdaccio (runs once)
build_and_publish:
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
- name: Use Node.js 22.x
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 22.x
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: '1.3.10'
- name: Install Verdaccio
run: |
npm install -g verdaccio
npm install -g wait-on
mkdir -p $HOME/.config/verdaccio
cp -v ./.github/workflows/verdaccio/config.yaml $HOME/.config/verdaccio/config.yaml
nohup verdaccio --config $HOME/.config/verdaccio/config.yaml &
wait-on http://localhost:4873
TOKEN_RES=$(curl -XPUT \
-H "Content-type: application/json" \
-d '{ "name": "test", "password": "test" }' \
'http://localhost:4873/-/user/org.couchdb.user:test')
TOKEN=$(echo "$TOKEN_RES" | jq -r '.token')
npm set //localhost:4873/:_authToken $TOKEN
- name: bun install
run: bun install --frozen-lockfile
env:
CI: true
- name: Publish to Verdaccio
run: |
nohup verdaccio --config $HOME/.config/verdaccio/config.yaml &
wait-on http://localhost:4873
bunx lerna publish prepatch --preid ci --no-push --no-git-tag-version --no-commit-hooks --force-publish "*" --yes --dist-tag ci --registry http://localhost:4873
- name: Package Verdaccio storage
run: |
cd $HOME/.config/verdaccio
tar -czf verdaccio-storage.tar.gz storage htpasswd
- name: Upload Verdaccio storage
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: verdaccio-storage
path: ~/.config/verdaccio/verdaccio-storage.tar.gz
retention-days: 1
# Job 2: Test installation on various OS/Node combinations
test:
needs: build_and_publish
runs-on: ${{ matrix.os }}
timeout-minutes: 45
permissions:
contents: read
strategy:
matrix:
# For PRs: run minimal matrix (1 job). For push: run full matrix (9 jobs).
# Only non-EOL Node versions are tested: native deps (e.g. better-sqlite3)
# stop publishing prebuilt binaries for EOL versions, and the node-gyp
# bundled with an EOL Node cannot drive newer Visual Studio releases.
os: ${{ github.event_name == 'pull_request' && fromJSON('["ubuntu-latest"]') || fromJSON('["ubuntu-latest", "windows-latest", "macos-latest"]') }}
node-version: ${{ github.event_name == 'pull_request' && fromJSON('["22.x"]') || fromJSON('["22.x", "24.x", "26.x"]') }}
fail-fast: false
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: ${{ matrix.node-version }}
- name: Download Verdaccio storage
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: verdaccio-storage
path: ~/verdaccio-download
- name: Setup Verdaccio with pre-built packages
run: |
npm install -g verdaccio
npm install -g wait-on
mkdir -p $HOME/.config/verdaccio
cp -v ./.github/workflows/verdaccio/config.yaml $HOME/.config/verdaccio/config.yaml
# Extract the pre-built storage
cd $HOME/.config/verdaccio
tar -xzf ~/verdaccio-download/verdaccio-storage.tar.gz
# Start Verdaccio
nohup verdaccio --config $HOME/.config/verdaccio/config.yaml &
wait-on http://localhost:4873
# Setup auth token
TOKEN_RES=$(curl -XPUT \
-H "Content-type: application/json" \
-d '{ "name": "test", "password": "test" }' \
'http://localhost:4873/-/user/org.couchdb.user:test')
TOKEN=$(echo "$TOKEN_RES" | jq -r '.token')
npm set //localhost:4873/:_authToken $TOKEN
- name: Windows dependencies
if: matrix.os == 'windows-latest'
run: npm install -g @angular/cli
- name: Install via @vendure/create
run: |
mkdir -p $HOME/install
cd $HOME/install
nohup verdaccio --config $HOME/.config/verdaccio/config.yaml &
wait-on http://localhost:4873
npm set registry=http://localhost:4873
npm dist-tag ls @vendure/create
npx @vendure/create@ci test-app --ci --use-npm --log-level info
- name: Server smoke tests
run: |
cd $HOME/install/test-app
npm run dev &
node $GITHUB_WORKSPACE/.github/workflows/scripts/smoke-tests
- name: Kill dev server after smoke tests
shell: bash
run: |
# Kill everything on ports 3000 and 5173 so the dashboard tests can start fresh.
# `npm run dev` spawns child processes (server on 3000, dashboard Vite on 5173)
# that aren't killed by killing the parent, so we kill by port. Freeing 5173 here
# is essential: otherwise the smoke-test dashboard lingers and the next step's
# dashboard fails to bind it.
if [[ "$RUNNER_OS" == "Windows" ]]; then
# Windows: use netstat to find PIDs and taskkill
netstat -ano | grep -E ':(3000|5173)[[:space:]]' | grep 'LISTENING' | awk '{print $5}' | sort -u | xargs -r -I {} taskkill //F //PID {} 2>/dev/null || true
else
# Linux/macOS: use lsof
lsof -ti:3000,5173 | xargs kill 2>/dev/null || true
fi
- name: Copy files (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
cd ~/install/test-app
New-Item -ItemType Directory -Force -Path src/plugins/test-plugin
Copy-Item "$env:GITHUB_WORKSPACE/.github/workflows/scripts/test-plugin/*" -Destination "src/plugins/test-plugin/" -Recurse -Force
Copy-Item "$env:GITHUB_WORKSPACE/.github/workflows/scripts/setup-test-plugin.js" -Destination "./setup-test-plugin.js"
- name: Copy files (Unix)
if: runner.os != 'Windows'
run: |
cd ~/install/test-app
mkdir -p src/plugins/test-plugin
cp -r "$GITHUB_WORKSPACE/.github/workflows/scripts/test-plugin/." src/plugins/test-plugin/
cp "$GITHUB_WORKSPACE/.github/workflows/scripts/setup-test-plugin.js" ./setup-test-plugin.js
- name: Run setup script
shell: bash
run: |
cd ~/install/test-app
node setup-test-plugin.js
- name: Cache Playwright browsers
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ hashFiles('**/bun.lock') }}
restore-keys: |
playwright-${{ runner.os }}-
- name: Install Playwright
run: |
cd ~/install/test-app
npm install --no-save playwright
npx playwright install chromium
npx playwright install-deps chromium
- name: Start dashboard and run tests
run: |
cd ~/install/test-app
# `npm run dev` already starts BOTH the Vendure server (port 3000) and the
# dashboard Vite dev server (port 5173) concurrently. Starting a second Vite
# on 5173 here caused an intermittent EADDRINUSE race against the one that
# `npm run dev` had already bound, so we rely on the single dev process.
npm run dev &
DEV_PID=$!
# Wait for the server (use /health endpoint, not root) and the dashboard to be available
wait-on http://localhost:3000/health --timeout 60000
wait-on http://localhost:5173/dashboard --timeout 120000
# Run the dashboard tests
NODE_PATH=~/install/test-app/node_modules node $GITHUB_WORKSPACE/.github/workflows/scripts/dashboard-tests.js
# Clean up dev server process
kill $DEV_PID 2>/dev/null || true
- name: Upload dashboard test screenshots
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: dashboard-test-screenshots-${{ matrix.os }}-${{ matrix.node-version }}
path: /tmp/dashboard-test-*.png
retention-days: 28
# Job 3: Verify `@vendure/create` works end-to-end when invoked via bun, pnpm and yarn.
# The package manager is detected from npm_config_user_agent (which bunx / pnpm dlx /
# yarn dlx set), so the install step and generated project must use that manager rather
# than hard-coding npm (#4390). pnpm and yarn are deliberately NOT pinned: their current
# releases are what users get, and policy changes in new majors (e.g. pnpm 11 ignoring
# the package.json pnpm field, yarn 4.14 disabling build scripts) must fail here (#4932).
test_package_managers:
needs: build_and_publish
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
strategy:
matrix:
include:
# $CREATE_VERSION is resolved from the ci dist-tag at run time. The tag
# itself is not passed to dlx because Verdaccio serves pnpm's abbreviated
# metadata requests a stale/merged tag map, resolving @ci to an upstream
# nightly instead of the locally published version.
- pm: bun
scaffold: bunx @vendure/create@$CREATE_VERSION test-app --ci --log-level info
- pm: pnpm
scaffold: pnpm dlx @vendure/create@$CREATE_VERSION test-app --ci --log-level info
- pm: yarn
scaffold: yarn dlx @vendure/create@$CREATE_VERSION test-app --ci --log-level info
fail-fast: false
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
- name: Use Node.js 22.x
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 22.x
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: '1.3.10'
- name: Enable pnpm and yarn via corepack
run: |
# The runner's bundled corepack maps yarn@stable to an outdated release;
# updating corepack first gives the current one that users actually get.
npm install -g corepack@latest
corepack enable
corepack prepare pnpm@latest --activate
corepack prepare yarn@stable --activate
pnpm --version
yarn --version
- name: Download Verdaccio storage
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: verdaccio-storage
path: ~/verdaccio-download
- name: Setup Verdaccio with pre-built packages
run: |
npm install -g verdaccio
npm install -g wait-on
mkdir -p $HOME/.config/verdaccio
cp -v ./.github/workflows/verdaccio/config.yaml $HOME/.config/verdaccio/config.yaml
cd $HOME/.config/verdaccio
tar -xzf ~/verdaccio-download/verdaccio-storage.tar.gz
nohup verdaccio --config $HOME/.config/verdaccio/config.yaml &
wait-on http://localhost:4873
# Register a Verdaccio user and capture an auth token.
TOKEN_RES=$(curl -XPUT \
-H "Content-type: application/json" \
-d '{ "name": "test", "password": "test" }' \
'http://localhost:4873/-/user/org.couchdb.user:test')
TOKEN=$(echo "$TOKEN_RES" | jq -r '.token')
# npm + pnpm read ~/.npmrc; bun is pointed at Verdaccio via the
# npm_config_registry env var on the install step (see below).
npm set registry=http://localhost:4873
npm set //localhost:4873/:_authToken $TOKEN
- name: Install via @vendure/create using ${{ matrix.pm }}
# bun ignores the home-directory ~/.npmrc (oven-sh/bun#22971) and does not walk
# up to a parent .npmrc/bunfig, but it DOES honour the npm_config_registry env
# var — and so does the scaffolded project's nested install (it inherits the
# env). This is the one mechanism that reaches both bunx and the nested install.
# Yarn Berry reads neither ~/.npmrc nor npm_config_registry: it needs its own
# YARN_NPM_REGISTRY_SERVER env var, plus the http whitelist since Verdaccio
# is plain http.
env:
CI: true
npm_config_registry: http://localhost:4873/
YARN_NPM_REGISTRY_SERVER: http://localhost:4873/
YARN_UNSAFE_HTTP_WHITELIST: localhost
# Yarn quarantines versions published less than npmMinimalAgeGate ago
# (default 1d, YN0016) — the packages under test are seconds old.
YARN_NPM_MINIMAL_AGE_GATE: 0
run: |
mkdir -p $HOME/install
cd $HOME/install
npm dist-tag ls @vendure/create
CREATE_VERSION=$(npm view @vendure/create@ci version)
echo "Resolved @vendure/create@ci -> $CREATE_VERSION"
# No --use-npm: the manager is detected from the invoking bunx / pnpm dlx.
${{ matrix.scaffold }}
- name: Assert the generated project used ${{ matrix.pm }}
run: |
cd $HOME/install/test-app
case "${{ matrix.pm }}" in
bun) test -f bun.lock || { echo "Expected bun.lock to exist"; ls -la; exit 1; } ;;
pnpm) test -f pnpm-lock.yaml || { echo "Expected pnpm-lock.yaml to exist"; ls -la; exit 1; } ;;
yarn) test -f yarn.lock || { echo "Expected yarn.lock to exist"; ls -la; exit 1; } ;;
esac
echo "Lockfile for ${{ matrix.pm }} present ✓"
- name: Server smoke tests
run: |
cd $HOME/install/test-app
${{ matrix.pm }} run dev &
node $GITHUB_WORKSPACE/.github/workflows/scripts/smoke-tests
- name: Kill dev server after smoke tests
if: always()
run: |
lsof -ti:3000,5173 | xargs kill 2>/dev/null || true
# Job 4: Exercise the Quick Start PostgreSQL path (docker compose up + readiness wait
# + populate against postgres), which `--ci` alone never touches. Runs three creates on
# the same runner — two of them monorepo — because the compose project-name collision
# that motivated this job (#4932) only bites from the second monorepo project onwards.
test_quickstart_postgres:
needs: build_and_publish
runs-on: ubuntu-latest
timeout-minutes: 45
permissions:
contents: read
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
- name: Use Node.js 22.x
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 22.x
- name: Download Verdaccio storage
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: verdaccio-storage
path: ~/verdaccio-download
- name: Setup Verdaccio with pre-built packages
run: |
npm install -g verdaccio
npm install -g wait-on
mkdir -p $HOME/.config/verdaccio
cp -v ./.github/workflows/verdaccio/config.yaml $HOME/.config/verdaccio/config.yaml
cd $HOME/.config/verdaccio
tar -xzf ~/verdaccio-download/verdaccio-storage.tar.gz
nohup verdaccio --config $HOME/.config/verdaccio/config.yaml &
wait-on http://localhost:4873
TOKEN_RES=$(curl -XPUT \
-H "Content-type: application/json" \
-d '{ "name": "test", "password": "test" }' \
'http://localhost:4873/-/user/org.couchdb.user:test')
TOKEN=$(echo "$TOKEN_RES" | jq -r '.token')
npm set registry=http://localhost:4873
npm set //localhost:4873/:_authToken $TOKEN
# The install directory deliberately contains a space: file URLs percent-encode
# it (%20), which used to leak into filesystem paths in the dashboard's vite
# plugins and break `npm run dev` (#4931).
- name: Quick Start with Postgres (single project)
timeout-minutes: 15
run: |
mkdir -p "$HOME/install dir"
cd "$HOME/install dir"
npx @vendure/create@ci shop-pg --ci --db postgres --use-npm --log-level info
- name: Dev server smoke test from a path containing a space
timeout-minutes: 15
run: |
cd "$HOME/install dir/shop-pg"
npm run dev &
wait-on http://localhost:3000/health --timeout 120000
# The dashboard Vite server failed to start when the project path
# percent-encoded (#4931), so it becoming reachable is the regression check.
wait-on http://localhost:5173/dashboard --timeout 180000
lsof -ti:3000,5173 | xargs kill 2>/dev/null || true
- name: Stop containers so the next project can bind port 6543
run: docker ps -q | xargs -r docker stop
- name: Quick Start with Postgres (monorepo, first)
timeout-minutes: 15
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
cd "$HOME/install dir"
npx @vendure/create@ci shop-mono-a --ci --db postgres --with-storefront --use-npm --log-level info
- name: Stop containers so the next project can bind port 6543
run: docker ps -q | xargs -r docker stop
- name: Quick Start with Postgres (monorepo, second — compose collision regression)
timeout-minutes: 15
# Deliberately runs with the previous monorepo project's stopped containers and
# volumes still present: before the fix, Compose derived the project name from
# the apps/server directory for BOTH projects and hung forever on an
# unanswerable "Recreate volume?" prompt.
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
cd "$HOME/install dir"
npx @vendure/create@ci shop-mono-b --ci --db postgres --with-storefront --use-npm --log-level info
- name: Assert each project got its own Compose project
run: |
docker ps -a --format '{{.Names}}' | sort
for project in shop-pg shop-mono-a shop-mono-b; do
docker ps -a --format '{{.Names}}' | grep -q "^${project}-postgres_db-1$" \
|| { echo "Expected container ${project}-postgres_db-1 to exist"; exit 1; }
done