426e9eeabd
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / lint-and-format (push) Has been cancelled
ci / build (push) Has been cancelled
ci / dev-startup (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format + Type Safety Ratchet (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
Chat shell gestures / Chat shell gesture + parity e2e (push) Has been cancelled
Cloud Gateway Discord / Test (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Has been cancelled
Build Agent Image / build-and-push (push) Has been cancelled
Dev Smoke / bun run dev onboarding chat (push) Has been cancelled
Dev Smoke / Vite HMR dependency-level smoke (push) Has been cancelled
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Has been cancelled
Publish @elizaos/example-code / check_npm (push) Has been cancelled
Publish @elizaos/example-code / publish_npm (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / verify_version (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / publish_npm (push) Has been cancelled
Sandbox Live Smoke / Sandbox live smoke (push) Has been cancelled
Snap Build & Test / Build Snap (amd64) (push) Has been cancelled
Snap Build & Test / Build Snap (arm64) (push) Has been cancelled
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Has been cancelled
Cloud Gateway Webhook / Test (push) Has been cancelled
Cloud Tests / lint-and-types (push) Has been cancelled
Cloud Tests / unit-tests (push) Has been cancelled
Cloud Tests / integration-tests (push) Has been cancelled
Cloud Tests / e2e-tests (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Apps Worker (Product 2) / Determine environment (push) Has been cancelled
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Has been cancelled
Deploy Eliza Provisioning Worker / Determine environment (push) Has been cancelled
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Has been cancelled
Dev Smoke / Classify changed paths (push) Has been cancelled
supply-chain / sbom (push) Has been cancelled
supply-chain / vulnerability-scan (push) Has been cancelled
Build, Push & Deploy to Phala Cloud / build-and-push (push) Has been cancelled
Test Packaging / Validate Packaging Configs (push) Has been cancelled
Test Packaging / Build & Test PyPI Package (push) Has been cancelled
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Has been cancelled
Test Packaging / Pack & Test JS Tarballs (push) Has been cancelled
UI Fixture E2E / ui-fixture-e2e (push) Has been cancelled
UI Fixture E2E / fixture-e2e (push) Has been cancelled
UI Story Gate / story-gate (push) Has been cancelled
vault-ci / test (macos-latest) (push) Has been cancelled
vault-ci / test (ubuntu-latest) (push) Has been cancelled
vault-ci / test (windows-latest) (push) Has been cancelled
vault-ci / app-core wiring tests (push) Has been cancelled
verify-patches / verify patches/CHECKSUMS.sha256 (push) Has been cancelled
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Has been cancelled
Voice Benchmark Smoke / voice bench smoke summary (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Has been cancelled
239 lines
7.1 KiB
JavaScript
239 lines
7.1 KiB
JavaScript
/** Supports app-core build, packaging, or development orchestration for test parallel mjs. */
|
|
import { spawn } from "node:child_process";
|
|
import fs from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
|
|
const resolvedBunCmd =
|
|
process.env.BUN && fs.existsSync(process.env.BUN)
|
|
? process.env.BUN
|
|
: process.env.BUN_INSTALL
|
|
? path.join(process.env.BUN_INSTALL, "bin", "bun")
|
|
: "bun";
|
|
const bunCmd = fs.existsSync(resolvedBunCmd) ? resolvedBunCmd : "bun";
|
|
const nodeCmd = process.execPath || "node";
|
|
|
|
/**
|
|
* Each entry describes a test suite to run in parallel.
|
|
*
|
|
* - `vitest: true` entries receive --maxWorkers and vitest-specific CI flags.
|
|
* - Entries may specify a `cwd` to run from a different directory.
|
|
* - Entries may specify a `cmd` to override the default (`bunx`).
|
|
* - `forceSerial: true` entries always run after parallel groups.
|
|
* - `maxWorkers` lets a suite pin worker concurrency.
|
|
*
|
|
* Opt-in UI browser E2E (Playwright): set ELIZA_TEST_UI_PLAYWRIGHT=1.
|
|
* ELIZA_TEST_UI_TESTCAFE remains as a legacy alias for the same suite.
|
|
*/
|
|
const runs = [
|
|
{
|
|
name: "app-unit",
|
|
cmd: nodeCmd,
|
|
args: [path.join(".", "node_modules", ".bin", "vitest"), "run"],
|
|
vitest: true,
|
|
cwd: "packages/app",
|
|
reportFile: path.join(os.tmpdir(), "eliza-vitest-app-unit-report.json"),
|
|
},
|
|
{
|
|
name: "unit",
|
|
cmd: bunCmd,
|
|
args: [
|
|
"x",
|
|
"vitest",
|
|
"run",
|
|
"--config",
|
|
"eliza/packages/test/vitest/default.config.ts",
|
|
],
|
|
vitest: true,
|
|
reportFile: path.join(os.tmpdir(), "eliza-vitest-unit-report.json"),
|
|
},
|
|
{
|
|
name: "integration",
|
|
cmd: bunCmd,
|
|
args: ["run", "test:integration"],
|
|
forceSerial: true,
|
|
},
|
|
{
|
|
name: "e2e",
|
|
cmd: bunCmd,
|
|
args: ["run", "test:e2e"],
|
|
forceSerial: true,
|
|
},
|
|
{
|
|
name: "orchestrator-integration",
|
|
cmd: bunCmd,
|
|
args: ["run", "test:orchestrator:integration"],
|
|
forceSerial: true,
|
|
},
|
|
];
|
|
|
|
if (
|
|
process.env.ELIZA_TEST_UI_PLAYWRIGHT === "1" ||
|
|
process.env.ELIZA_TEST_UI_TESTCAFE === "1"
|
|
) {
|
|
runs.push({
|
|
name: "ui-playwright",
|
|
cmd: bunCmd,
|
|
args: ["run", "--cwd", "packages/app", "test:e2e"],
|
|
forceSerial: true,
|
|
});
|
|
}
|
|
|
|
const children = new Set();
|
|
const isCI = process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true";
|
|
const isMacOS =
|
|
process.platform === "darwin" || process.env.RUNNER_OS === "macOS";
|
|
const isWindows =
|
|
process.platform === "win32" || process.env.RUNNER_OS === "Windows";
|
|
const isWindowsCi = isCI && isWindows;
|
|
// On macOS, Vitest forks pool workers sometimes crash during jsdom GC
|
|
// teardown (known V8/jsdom interaction). Use dangerouslyIgnoreUnhandledErrors
|
|
// to prevent spurious CI failures from these non-test-affecting worker exits.
|
|
const needsDangerouslyIgnore = isWindowsCi || (isCI && isMacOS);
|
|
const shardOverride = Number.parseInt(process.env.ELIZA_TEST_SHARDS ?? "", 10);
|
|
const shardCount = isWindowsCi
|
|
? Number.isFinite(shardOverride) && shardOverride > 1
|
|
? shardOverride
|
|
: 2
|
|
: 1;
|
|
const ciWorkerArgs = needsDangerouslyIgnore
|
|
? ["--no-file-parallelism", "--dangerouslyIgnoreUnhandledErrors"]
|
|
: [];
|
|
const overrideWorkers = Number.parseInt(
|
|
process.env.ELIZA_TEST_WORKERS ?? "",
|
|
10,
|
|
);
|
|
const resolvedOverride =
|
|
Number.isFinite(overrideWorkers) && overrideWorkers > 0
|
|
? overrideWorkers
|
|
: null;
|
|
const defaultParallelRuns = [];
|
|
const defaultSerialRuns = runs;
|
|
const parallelRuns = isWindowsCi ? [] : defaultParallelRuns;
|
|
const serialRuns = isWindowsCi ? runs : defaultSerialRuns;
|
|
const localWorkers = 2;
|
|
const parallelCount = Math.max(1, parallelRuns.length || 1);
|
|
const perRunWorkers = Math.max(1, Math.floor(localWorkers / parallelCount));
|
|
const macCiWorkers = isCI && isMacOS ? 1 : perRunWorkers;
|
|
// Use Vitest defaults for local unit runs. Forcing low local worker counts can leave the
|
|
// child Vitest process hanging after completion on macOS. Keep the explicit cap only for
|
|
// CI, where we want deterministic resource usage and known crash avoidance behavior.
|
|
const maxWorkers = resolvedOverride ?? (isCI ? macCiWorkers : null);
|
|
|
|
const WARNING_SUPPRESSION_FLAGS = [
|
|
"--disable-warning=ExperimentalWarning",
|
|
"--disable-warning=DEP0040",
|
|
"--disable-warning=DEP0060",
|
|
];
|
|
const LOCALSTORAGE_NODE_OPTION_PATTERN =
|
|
/(^|\s)--localstorage-file(?:=\S+)?(?=\s|$)/g;
|
|
|
|
function sanitiseNodeOptions(nodeOptions) {
|
|
return nodeOptions
|
|
.replace(LOCALSTORAGE_NODE_OPTION_PATTERN, " ")
|
|
.replace(/\s+/g, " ")
|
|
.trim();
|
|
}
|
|
|
|
function buildChildEnv(baseEnv, cwd) {
|
|
const nextEnv = { ...baseEnv };
|
|
for (const key of Object.keys(nextEnv)) {
|
|
if (key.startsWith("npm_") || key === "INIT_CWD") {
|
|
delete nextEnv[key];
|
|
}
|
|
}
|
|
if (cwd) {
|
|
nextEnv.PWD = path.resolve(cwd);
|
|
}
|
|
return nextEnv;
|
|
}
|
|
|
|
const runOnce = (entry, extraArgs = []) =>
|
|
new Promise((resolve) => {
|
|
if (entry.reportFile) {
|
|
try {
|
|
fs.rmSync(entry.reportFile, { force: true });
|
|
} catch {
|
|
// Best-effort cleanup only.
|
|
}
|
|
}
|
|
const entryWorkers =
|
|
typeof entry.maxWorkers === "number" ? entry.maxWorkers : maxWorkers;
|
|
const vitestExtras = entry.vitest
|
|
? [
|
|
...(entry.reportFile
|
|
? ["--reporter", "json", "--outputFile", entry.reportFile]
|
|
: []),
|
|
...(entryWorkers ? ["--maxWorkers", String(entryWorkers)] : []),
|
|
...ciWorkerArgs,
|
|
]
|
|
: [];
|
|
const args = [...entry.args, ...vitestExtras, ...extraArgs];
|
|
const nodeOptions = process.env.NODE_OPTIONS ?? "";
|
|
const nextNodeOptions = WARNING_SUPPRESSION_FLAGS.reduce(
|
|
(acc, flag) => (acc.includes(flag) ? acc : `${acc} ${flag}`.trim()),
|
|
nodeOptions,
|
|
);
|
|
const cmd = entry.cmd ?? "bun";
|
|
const child = spawn(cmd, args, {
|
|
stdio: "inherit",
|
|
...(entry.cwd ? { cwd: entry.cwd } : {}),
|
|
env: {
|
|
...buildChildEnv(process.env, entry.cwd),
|
|
VITEST_GROUP: entry.name,
|
|
ELIZA_LIVE_TEST: "0",
|
|
NODE_OPTIONS: sanitiseNodeOptions(nextNodeOptions),
|
|
NODE_NO_WARNINGS: process.env.NODE_NO_WARNINGS ?? "1",
|
|
},
|
|
shell: process.platform === "win32",
|
|
});
|
|
children.add(child);
|
|
child.on("exit", (code, signal) => {
|
|
children.delete(child);
|
|
resolve(code ?? (signal ? 1 : 0));
|
|
});
|
|
});
|
|
|
|
const run = async (entry) => {
|
|
// Only vitest entries support sharding.
|
|
if (shardCount <= 1 || !entry.vitest) {
|
|
return runOnce(entry);
|
|
}
|
|
for (let shardIndex = 1; shardIndex <= shardCount; shardIndex += 1) {
|
|
// eslint-disable-next-line no-await-in-loop
|
|
const code = await runOnce(entry, [
|
|
"--shard",
|
|
`${shardIndex}/${shardCount}`,
|
|
]);
|
|
if (code !== 0) {
|
|
return code;
|
|
}
|
|
}
|
|
return 0;
|
|
};
|
|
|
|
const shutdown = (signal) => {
|
|
for (const child of children) {
|
|
child.kill(signal);
|
|
}
|
|
};
|
|
|
|
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
|
|
const parallelCodes = await Promise.all(parallelRuns.map(run));
|
|
const failedParallel = parallelCodes.find((code) => code !== 0);
|
|
if (failedParallel !== undefined) {
|
|
process.exit(failedParallel);
|
|
}
|
|
|
|
for (const entry of serialRuns) {
|
|
// eslint-disable-next-line no-await-in-loop
|
|
const code = await run(entry);
|
|
if (code !== 0) {
|
|
process.exit(code);
|
|
}
|
|
}
|
|
|
|
process.exit(0);
|