fix(ci): address macOS vitest worker crash flakiness
- vitest.config.ts: Use singleFork mode on macOS CI and longer teardown timeout to allow proper cleanup of native modules (node:sqlite, chokidar) - test/setup.ts: Clean up warning filter during test teardown - src/infra/warnings.ts: Return cleanup function from installProcessWarningFilter - .github/workflows/ci.yml: Remove retry loop now that root cause is fixed
This commit is contained in:
parent
1750d0855b
commit
66ef42a2f9
@ -6,6 +6,11 @@ type Warning = Error & {
|
||||
message?: string;
|
||||
};
|
||||
|
||||
type WarningFilterState = {
|
||||
installed: boolean;
|
||||
listener?: (warning: Warning) => void;
|
||||
};
|
||||
|
||||
function shouldIgnoreWarning(warning: Warning): boolean {
|
||||
if (warning.code === "DEP0040" && warning.message?.includes("punycode")) {
|
||||
return true;
|
||||
@ -22,15 +27,33 @@ function shouldIgnoreWarning(warning: Warning): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function installProcessWarningFilter(): void {
|
||||
/**
|
||||
* Install a process warning filter that suppresses known benign warnings.
|
||||
* Returns a cleanup function to remove the listener (useful for test teardown).
|
||||
*/
|
||||
export function installProcessWarningFilter(): () => void {
|
||||
const globalState = globalThis as typeof globalThis & {
|
||||
[warningFilterKey]?: { installed: boolean };
|
||||
[warningFilterKey]?: WarningFilterState;
|
||||
};
|
||||
if (globalState[warningFilterKey]?.installed) return;
|
||||
globalState[warningFilterKey] = { installed: true };
|
||||
if (globalState[warningFilterKey]?.installed) {
|
||||
// Already installed - return a no-op cleanup
|
||||
return () => {};
|
||||
}
|
||||
|
||||
process.on("warning", (warning: Warning) => {
|
||||
const listener = (warning: Warning) => {
|
||||
if (shouldIgnoreWarning(warning)) return;
|
||||
process.stderr.write(`${warning.stack ?? warning.toString()}\n`);
|
||||
});
|
||||
};
|
||||
|
||||
globalState[warningFilterKey] = { installed: true, listener };
|
||||
process.on("warning", listener);
|
||||
|
||||
return () => {
|
||||
const state = globalState[warningFilterKey];
|
||||
if (state?.listener) {
|
||||
process.off("warning", state.listener);
|
||||
state.listener = undefined;
|
||||
state.installed = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -15,10 +15,13 @@ import { setActivePluginRegistry } from "../src/plugins/runtime.js";
|
||||
import { createTestRegistry } from "../src/test-utils/channel-plugins.js";
|
||||
import { withIsolatedTestHome } from "./test-env";
|
||||
|
||||
installProcessWarningFilter();
|
||||
const cleanupWarningFilter = installProcessWarningFilter();
|
||||
|
||||
const testEnv = withIsolatedTestHome();
|
||||
afterAll(() => testEnv.cleanup());
|
||||
afterAll(() => {
|
||||
testEnv.cleanup();
|
||||
cleanupWarningFilter();
|
||||
});
|
||||
const pickSendFn = (id: ChannelId, deps?: OutboundSendDeps) => {
|
||||
switch (id) {
|
||||
case "discord":
|
||||
|
||||
@ -11,6 +11,9 @@ const localWorkers = Math.max(4, Math.min(16, os.cpus().length));
|
||||
// Cap CI workers: Windows/macOS get 2 (flaky worker crashes), Linux gets 3
|
||||
const ciWorkers = isWindows || isMacOS ? 2 : 3;
|
||||
|
||||
// macOS CI needs longer teardown for native module cleanup (sqlite, chokidar)
|
||||
const macOSCI = isCI && isMacOS;
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
@ -20,6 +23,8 @@ export default defineConfig({
|
||||
test: {
|
||||
testTimeout: 120_000,
|
||||
hookTimeout: isWindows ? 180_000 : 120_000,
|
||||
// Longer teardown on macOS CI for native module cleanup (node:sqlite, etc.)
|
||||
teardownTimeout: macOSCI ? 30_000 : 10_000,
|
||||
pool: "forks",
|
||||
maxWorkers: isCI ? ciWorkers : localWorkers,
|
||||
include: [
|
||||
|
||||
Loading…
Reference in New Issue
Block a user