Skip to content

Commit fe91ccf

Browse files
fix(ci): use DIFY_E2E_INCLUDE env to override vitest include list per job
Previously, passing positional file args to pnpm test:e2e had no effect because vitest.e2e.config.ts include list took precedence, causing every parallel job to run the full suite and hit the 20-minute timeout. vitest.e2e.config.ts: - Add DIFY_E2E_INCLUDE env var (comma-separated globs, replaces SINGLE_FILE) - DIFY_E2E_SINGLE_FILE kept as deprecated alias for back-compat - When set, include list is built from DIFY_E2E_INCLUDE instead of the hardcoded full-suite list cli-e2e.yml: - Every suite job now sets DIFY_E2E_INCLUDE to target its own files - Remove positional file args (they were silently ignored by vitest config) - Standardise smoke filter: FILTER_ARGS array -> inline -t arg - timeout-minutes: discovery 20->15, run/* 20->35 (CI ~5x slower)
1 parent 2d22d87 commit fe91ccf

2 files changed

Lines changed: 55 additions & 28 deletions

File tree

‎.github/workflows/cli-e2e.yml‎

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,13 @@ jobs:
149149
- name: Run config + help (DIFY_E2E_MODE=local)
150150
env:
151151
DIFY_E2E_MODE: local
152+
DIFY_E2E_INCLUDE: "test/e2e/suites/framework/help.e2e.ts,test/e2e/suites/config/**/*.e2e.ts"
152153
run: |
153-
if [ "${{ inputs.test_scope }}" = "smoke" ]; then FILTER_ARGS=(-t "\[P0\]"); else FILTER_ARGS=(); fi
154-
pnpm test:e2e -- "${FILTER_ARGS[@]}" \
155-
test/e2e/suites/framework/help.e2e.ts \
156-
test/e2e/suites/config
154+
if [ "${{ inputs.test_scope }}" = "smoke" ]; then
155+
pnpm test:e2e -- -t "\[P0\]"
156+
else
157+
pnpm test:e2e
158+
fi
157159
158160
# ════════════════════════════════════════════════════════════════════════════
159161
# 1-B. framework + output + error-handling (parallel with run/discovery)
@@ -194,16 +196,14 @@ jobs:
194196
DIFY_E2E_WORKSPACE_NAME: ${{ needs.provision.outputs.workspace_name }}
195197
DIFY_E2E_CHAT_APP_ID: ${{ needs.provision.outputs.chat_app_id }}
196198
DIFY_E2E_WORKFLOW_APP_ID: ${{ needs.provision.outputs.workflow_app_id }}
199+
env:
200+
DIFY_E2E_INCLUDE: "test/e2e/suites/framework/global-flags.e2e.ts,test/e2e/suites/output/**/*.e2e.ts,test/e2e/suites/error-handling/**/*.e2e.ts"
197201
run: |
198-
FILES=(
199-
test/e2e/suites/framework/global-flags.e2e.ts
200-
test/e2e/suites/output/json-yaml-output.e2e.ts
201-
test/e2e/suites/output/table-output.e2e.ts
202-
test/e2e/suites/error-handling/error-messages.e2e.ts
203-
test/e2e/suites/error-handling/exit-codes.e2e.ts
204-
)
205-
if [ "${{ inputs.test_scope }}" = "smoke" ]; then FILTER_ARGS=(-t "\[P0\]"); else FILTER_ARGS=(); fi
206-
pnpm test:e2e -- ${FILTER} "${FILES[@]}"
202+
if [ "${{ inputs.test_scope }}" = "smoke" ]; then
203+
pnpm test:e2e -- -t "\[P0\]"
204+
else
205+
pnpm test:e2e
206+
fi
207207
208208
# ════════════════════════════════════════════════════════════════════════════
209209
# 1-C. Discovery (parallel)
@@ -245,9 +245,14 @@ jobs:
245245
DIFY_E2E_WS2_ID: ${{ needs.provision.outputs.ws2_id }}
246246
DIFY_E2E_CHAT_APP_ID: ${{ needs.provision.outputs.chat_app_id }}
247247
DIFY_E2E_WORKFLOW_APP_ID: ${{ needs.provision.outputs.workflow_app_id }}
248+
env:
249+
DIFY_E2E_INCLUDE: "test/e2e/suites/discovery/**/*.e2e.ts"
248250
run: |
249-
pnpm test:e2e -- "${FILTER_ARGS[@]}" \
250-
$(find test/e2e/suites/discovery -name '*.e2e.ts' | sort)
251+
if [ "${{ inputs.test_scope }}" = "smoke" ]; then
252+
pnpm test:e2e -- -t "\[P0\]"
253+
else
254+
pnpm test:e2e
255+
fi
251256
252257
# ════════════════════════════════════════════════════════════════════════════
253258
# 1-D. Run suite — 5 files in matrix (parallel)
@@ -310,9 +315,14 @@ jobs:
310315
DIFY_E2E_HITL_EXTERNAL_APP_ID: ${{ needs.provision.outputs.hitl_external_app_id }}
311316
DIFY_E2E_HITL_SINGLE_ACTION_APP_ID: ${{ needs.provision.outputs.hitl_single_action_app_id }}
312317
DIFY_E2E_HITL_MULTI_NODE_APP_ID: ${{ needs.provision.outputs.hitl_multi_node_app_id }}
318+
env:
319+
DIFY_E2E_INCLUDE: "test/e2e/suites/run/${{ matrix.file }}"
313320
run: |
314-
pnpm test:e2e -- "${FILTER_ARGS[@]}" \
315-
test/e2e/suites/run/${{ matrix.file }}
321+
if [ "${{ inputs.test_scope }}" = "smoke" ]; then
322+
pnpm test:e2e -- -t "\[P0\]"
323+
else
324+
pnpm test:e2e
325+
fi
316326
317327
- name: Upload results on failure
318328
if: failure()
@@ -360,11 +370,14 @@ jobs:
360370
DIFY_E2E_WORKSPACE_ID: ${{ needs.provision.outputs.workspace_id }}
361371
DIFY_E2E_WORKSPACE_NAME: ${{ needs.provision.outputs.workspace_name }}
362372
DIFY_E2E_WS2_ID: ${{ needs.provision.outputs.ws2_id }}
373+
env:
374+
DIFY_E2E_INCLUDE: "test/e2e/suites/auth/login.e2e.ts,test/e2e/suites/auth/status.e2e.ts,test/e2e/suites/auth/whoami.e2e.ts"
363375
run: |
364-
pnpm test:e2e -- "${FILTER_ARGS[@]}" \
365-
test/e2e/suites/auth/login.e2e.ts \
366-
test/e2e/suites/auth/status.e2e.ts \
367-
test/e2e/suites/auth/whoami.e2e.ts
376+
if [ "${{ inputs.test_scope }}" = "smoke" ]; then
377+
pnpm test:e2e -- -t "\[P0\]"
378+
else
379+
pnpm test:e2e
380+
fi
368381
369382
# ════════════════════════════════════════════════════════════════════════════
370383
# 2. DESTRUCTIVE — auth/use + devices + logout + agent (serial, runs LAST)
@@ -438,9 +451,14 @@ jobs:
438451
439452
[ ${#FILES[@]} -eq 0 ] && { echo "Nothing to run."; exit 0; }
440453
441-
# Serial: fileParallelism is already false in vitest.e2e.config.ts
442-
pnpm test:e2e -- "${FILTER_ARGS[@]}" \
443-
"${FILES[@]}"
454+
# Pass files via DIFY_E2E_INCLUDE (comma-separated) so vitest
455+
# config's include list is overridden instead of ANDed.
456+
INCLUDE=$(IFS=,; echo "${FILES[*]}")
457+
if [ "${{ inputs.test_scope }}" = "smoke" ]; then
458+
DIFY_E2E_INCLUDE="$INCLUDE" pnpm test:e2e -- -t "\[P0\]"
459+
else
460+
DIFY_E2E_INCLUDE="$INCLUDE" pnpm test:e2e
461+
fi
444462
445463
- name: Upload results on failure
446464
if: failure()

‎cli/vitest.e2e.config.ts‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,18 @@ export default defineConfig({
5656
// E2E tests do NOT use the unit-test setup.ts (no globalThis stubs needed —
5757
// the real binary sets its own globals at startup).
5858
setupFiles: [],
59-
include: process.env.DIFY_E2E_SINGLE_FILE
60-
? [process.env.DIFY_E2E_SINGLE_FILE]
61-
: process.env.DIFY_E2E_MODE === 'local'
59+
// DIFY_E2E_INCLUDE: comma-separated glob patterns, e.g.
60+
// DIFY_E2E_INCLUDE="test/e2e/suites/run/run-app-basic.e2e.ts"
61+
// DIFY_E2E_INCLUDE="test/e2e/suites/run/**/*.e2e.ts"
62+
// DIFY_E2E_INCLUDE="test/e2e/suites/discovery/**/*.e2e.ts,test/e2e/suites/run/run-app-basic.e2e.ts"
63+
// Deprecated alias: DIFY_E2E_SINGLE_FILE (single path only, kept for back-compat)
64+
include: (() => {
65+
const raw = process.env.DIFY_E2E_INCLUDE ?? process.env.DIFY_E2E_SINGLE_FILE
66+
if (raw)
67+
return raw.split(',').map(s => s.trim()).filter(Boolean)
68+
return undefined
69+
})()
70+
?? (process.env.DIFY_E2E_MODE === 'local'
6271
? ['test/e2e/suites/framework/help.e2e.ts', 'test/e2e/suites/config/**/*.e2e.ts', 'test/e2e/suites/agent/**/*.e2e.ts']
6372
: [
6473
// auth tests first (most others depend on a valid session)
@@ -84,7 +93,7 @@ export default defineConfig({
8493
// devices + logout LAST — both can revoke tokens
8594
'test/e2e/suites/auth/devices.e2e.ts',
8695
'test/e2e/suites/auth/logout.e2e.ts',
87-
],
96+
]),
8897
// E2E calls a real staging server — allow plenty of time per test.
8998
testTimeout: 120_000,
9099
hookTimeout: 30_000,

0 commit comments

Comments
 (0)