|
66 | 66 | run: pnpm build |
67 | 67 | - |
68 | 68 | name: Run the backend tests |
69 | | - env: |
70 | | - # --report-on-fatalerror and friends write a Node diagnostic report |
71 | | - # (V8 stack, libuv handles, OS info) on fatal errors that bypass JS |
72 | | - # handlers — the failure mode we've been chasing on Windows + Node |
73 | | - # 24 since PR #7663. Reports land in node-report/ and are uploaded |
74 | | - # as an artifact if the step fails. |
75 | | - NODE_OPTIONS: "--report-on-fatalerror --report-uncaught-exception --report-on-signal --report-compact --report-directory=${{ github.workspace }}/node-report" |
76 | | - run: | |
77 | | - mkdir -p "${{ github.workspace }}/node-report" |
78 | | - pnpm test |
79 | | - - name: Upload Node diagnostic reports on failure |
80 | | - if: ${{ failure() }} |
81 | | - uses: actions/upload-artifact@v7 |
82 | | - with: |
83 | | - name: node-diagnostic-report-${{ runner.os }}-node${{ matrix.node }}-${{ github.job }} |
84 | | - path: node-report/ |
85 | | - if-no-files-found: ignore |
86 | | - retention-days: 7 |
| 69 | + run: pnpm test |
87 | 70 | - name: Run the new vitest tests |
88 | 71 | working-directory: src |
89 | 72 | run: pnpm run test:vitest |
@@ -153,19 +136,7 @@ jobs: |
153 | 136 | ep_table_of_contents |
154 | 137 | - |
155 | 138 | name: Run the backend tests |
156 | | - env: |
157 | | - NODE_OPTIONS: "--report-on-fatalerror --report-uncaught-exception --report-on-signal --report-compact --report-directory=${{ github.workspace }}/node-report" |
158 | | - run: | |
159 | | - mkdir -p "${{ github.workspace }}/node-report" |
160 | | - pnpm test |
161 | | - - name: Upload Node diagnostic reports on failure |
162 | | - if: ${{ failure() }} |
163 | | - uses: actions/upload-artifact@v7 |
164 | | - with: |
165 | | - name: node-diagnostic-report-${{ runner.os }}-node${{ matrix.node }}-${{ github.job }} |
166 | | - path: node-report/ |
167 | | - if-no-files-found: ignore |
168 | | - retention-days: 7 |
| 139 | + run: pnpm test |
169 | 140 | - name: Run the new vitest tests |
170 | 141 | working-directory: src |
171 | 142 | run: pnpm run test:vitest |
@@ -229,60 +200,9 @@ jobs: |
229 | 200 | name: Run the backend tests |
230 | 201 | shell: bash |
231 | 202 | working-directory: src |
232 | | - env: |
233 | | - NODE_OPTIONS: "--report-on-fatalerror --report-uncaught-exception --report-on-signal --report-compact --report-directory=${{ github.workspace }}/node-report" |
234 | | - run: | |
235 | | - mkdir -p "${{ github.workspace }}/node-report" |
236 | | - OUT="${{ github.workspace }}/node-report" |
237 | | - # Out-of-process OS-level watcher for the silent-ELIFECYCLE flake. |
238 | | - # In-process diagnostics (diagnostics.ts heartbeat + node-report |
239 | | - # snapshots) showed that during the death window the V8 main |
240 | | - # isolate is starved — heartbeat stops firing entirely, then the |
241 | | - # process is externally terminated, bypassing all JS handlers and |
242 | | - # Node's --report-on-fatalerror. To capture state during that |
243 | | - # starvation we need a process that doesn't depend on the dying |
244 | | - # process's event loop. A bash background loop polling Windows |
245 | | - # OS state every 500 ms gives us that: |
246 | | - # - netstat.log: localhost TCP socket states over time |
247 | | - # (TIME_WAIT/CLOSE_WAIT accumulation, handle exhaustion) |
248 | | - # - tasklist.log: node.exe process handle count, working set, |
249 | | - # CPU time — captured by the OS independent of V8. |
250 | | - # Both logs are appended to node-report/ which already gets |
251 | | - # uploaded as an artifact on failure. |
252 | | - ( |
253 | | - while true; do |
254 | | - ts=$(date '+%H:%M:%S.%3N') |
255 | | - { |
256 | | - echo "=== $ts ===" |
257 | | - netstat -an 2>/dev/null | grep -E "TCP\s+(127\.0\.0\.1|\[::1\])" || true |
258 | | - } >> "$OUT/netstat.log" |
259 | | - { |
260 | | - echo "=== $ts ===" |
261 | | - tasklist /v /fi "imagename eq node.exe" /fo csv 2>/dev/null || true |
262 | | - } >> "$OUT/tasklist.log" |
263 | | - sleep 0.5 |
264 | | - done |
265 | | - ) & |
266 | | - WATCHER_PID=$! |
267 | | - # --exit forces process.exit(failures) after the suite completes, |
268 | | - # closing the post-suite event-loop drain window where Windows + |
269 | | - # Node 24 hard-kills the process. Scoped to Windows so Linux/local |
270 | | - # runs still surface real handle leaks via natural drain. |
271 | | - set +e |
272 | | - pnpm test -- --exit |
273 | | - EXIT=$? |
274 | | - set -e |
275 | | - kill "$WATCHER_PID" 2>/dev/null || true |
276 | | - wait "$WATCHER_PID" 2>/dev/null || true |
277 | | - exit $EXIT |
278 | | - - name: Upload Node diagnostic reports on failure |
279 | | - if: ${{ failure() }} |
280 | | - uses: actions/upload-artifact@v7 |
281 | | - with: |
282 | | - name: node-diagnostic-report-${{ runner.os }}-node${{ matrix.node }}-${{ github.job }} |
283 | | - path: node-report/ |
284 | | - if-no-files-found: ignore |
285 | | - retention-days: 7 |
| 203 | + # --exit makes mocha call process.exit() after the run so a leaked handle |
| 204 | + # cannot hang the job on Windows. |
| 205 | + run: pnpm test -- --exit |
286 | 206 | - name: Run the new vitest tests |
287 | 207 | working-directory: src |
288 | 208 | run: pnpm run test:vitest |
@@ -374,60 +294,9 @@ jobs: |
374 | 294 | name: Run the backend tests |
375 | 295 | shell: bash |
376 | 296 | working-directory: src |
377 | | - env: |
378 | | - NODE_OPTIONS: "--report-on-fatalerror --report-uncaught-exception --report-on-signal --report-compact --report-directory=${{ github.workspace }}/node-report" |
379 | | - run: | |
380 | | - mkdir -p "${{ github.workspace }}/node-report" |
381 | | - OUT="${{ github.workspace }}/node-report" |
382 | | - # Out-of-process OS-level watcher for the silent-ELIFECYCLE flake. |
383 | | - # In-process diagnostics (diagnostics.ts heartbeat + node-report |
384 | | - # snapshots) showed that during the death window the V8 main |
385 | | - # isolate is starved — heartbeat stops firing entirely, then the |
386 | | - # process is externally terminated, bypassing all JS handlers and |
387 | | - # Node's --report-on-fatalerror. To capture state during that |
388 | | - # starvation we need a process that doesn't depend on the dying |
389 | | - # process's event loop. A bash background loop polling Windows |
390 | | - # OS state every 500 ms gives us that: |
391 | | - # - netstat.log: localhost TCP socket states over time |
392 | | - # (TIME_WAIT/CLOSE_WAIT accumulation, handle exhaustion) |
393 | | - # - tasklist.log: node.exe process handle count, working set, |
394 | | - # CPU time — captured by the OS independent of V8. |
395 | | - # Both logs are appended to node-report/ which already gets |
396 | | - # uploaded as an artifact on failure. |
397 | | - ( |
398 | | - while true; do |
399 | | - ts=$(date '+%H:%M:%S.%3N') |
400 | | - { |
401 | | - echo "=== $ts ===" |
402 | | - netstat -an 2>/dev/null | grep -E "TCP\s+(127\.0\.0\.1|\[::1\])" || true |
403 | | - } >> "$OUT/netstat.log" |
404 | | - { |
405 | | - echo "=== $ts ===" |
406 | | - tasklist /v /fi "imagename eq node.exe" /fo csv 2>/dev/null || true |
407 | | - } >> "$OUT/tasklist.log" |
408 | | - sleep 0.5 |
409 | | - done |
410 | | - ) & |
411 | | - WATCHER_PID=$! |
412 | | - # --exit forces process.exit(failures) after the suite completes, |
413 | | - # closing the post-suite event-loop drain window where Windows + |
414 | | - # Node 24 hard-kills the process. Scoped to Windows so Linux/local |
415 | | - # runs still surface real handle leaks via natural drain. |
416 | | - set +e |
417 | | - pnpm test -- --exit |
418 | | - EXIT=$? |
419 | | - set -e |
420 | | - kill "$WATCHER_PID" 2>/dev/null || true |
421 | | - wait "$WATCHER_PID" 2>/dev/null || true |
422 | | - exit $EXIT |
423 | | - - name: Upload Node diagnostic reports on failure |
424 | | - if: ${{ failure() }} |
425 | | - uses: actions/upload-artifact@v7 |
426 | | - with: |
427 | | - name: node-diagnostic-report-${{ runner.os }}-node${{ matrix.node }}-${{ github.job }} |
428 | | - path: node-report/ |
429 | | - if-no-files-found: ignore |
430 | | - retention-days: 7 |
| 297 | + # --exit makes mocha call process.exit() after the run so a leaked handle |
| 298 | + # cannot hang the job on Windows. |
| 299 | + run: pnpm test -- --exit |
431 | 300 | - name: Run the new vitest tests |
432 | 301 | working-directory: src |
433 | 302 | run: pnpm run test:vitest |
0 commit comments