Files
wehub-resource-sync 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
chore: import upstream snapshot with attribution
2026-07-13 12:43:05 +08:00

225 lines
7.6 KiB
JavaScript

/**
* Pure step-planning and command-argument construction for the one-command
* physical-iPhone e2e lane (`ios-device-e2e.mjs`, issue #14337).
*
* The lane chains three already-proven scripts — deploy → on-device BootCapture
* assertion → boot-trace logs — into one command. This module owns only the
* decisions unique to the physical-device lane: which steps run and the exact
* argv each chained child gets. Run assembly and reporting (step timing, the
* triage bundle, `summary.json`, artifact collection, inline conversion, junit)
* are the shared `lib/device-e2e-bundle.mjs` framework's job — the same one
* `android-e2e.mjs` and `ios-e2e.mjs` use — so all three lanes emit one
* summary shape (PR #14509 reconciliation onto the sibling bundle lib #14336).
* Keeping the argv construction here means the exact flags the lane hands each
* child are unit-tested against fixtures without a device.
*
* The on-device assertion is BootCapture, NOT `mobile-local-chat-smoke`: that
* smoke targets the iOS Simulator, so on a physical iPhone the XCUITest
* BootCapture harness ("did the freshly deployed app boot to home or an error
* card") is the on-device assertion of record (issue #14337, research doc 08 §4).
* BootCapture writes its filmstrip attachments into the smoke step's output dir,
* so that one on-device boot yields both the pass/fail verdict and the watchable
* filmstrip — there is no separate capture boot (a second identical BootCapture
* run would only re-boot the phone to produce bytes the smoke step already has).
*/
import path from "node:path";
/** Canonical step ids, in execution order. */
export const IOS_DEVICE_E2E_STEP_IDS = Object.freeze([
"deploy",
"smoke",
"logs",
]);
/**
* Plan the ordered steps for a physical-iPhone e2e run. Deploy + smoke are
* mandatory — this lane has no "vacuous" mode: a run that skipped the on-device
* assertion would print success without proving the phone booted the new build.
* The smoke step's BootCapture run already emits the watchable filmstrip, so
* there is no separate capture step. `--skip-logs` exists only to trim the
* (non-assertion) boot-trace pull for tight iteration.
*
* @param {{ skipLogs?: boolean }} [flags]
* @returns {Array<{ id: string, label: string }>}
*/
export function planIosDeviceE2eSteps({ skipLogs = false } = {}) {
const steps = [
{
id: "deploy",
label: "deploy signed App.app to the device (--skip-appexes)",
},
{
id: "smoke",
label:
"on-device BootCapture assertion + filmstrip (boots to home or error card)",
},
];
if (!skipLogs) {
steps.push({
id: "logs",
label: "pull the full-Bun boot-trace (--no-console)",
});
}
return steps;
}
/**
* Absolute node argv for the deploy step. `--skip-appexes` is the default
* unattended posture (PR #13174, research doc Q6): per-appex profiles need an
* ASC API key, so widget/keyboard/device-activity surfaces are stripped and the
* deploy logs that loudly. `--device` is always passed through so the whole lane
* pins one phone.
*
* @param {{ scriptsDir: string, deviceId: string, skipAppexes?: boolean,
* skipBuild?: boolean, noLaunch?: boolean, bundleId?: string | null }} opts
* @returns {{ cmd: string, args: string[] }}
*/
export function buildDeviceDeployCommand({
scriptsDir,
deviceId,
skipAppexes = true,
skipBuild = false,
noLaunch = false,
bundleId = null,
}) {
if (!deviceId)
throw new Error("buildDeviceDeployCommand: deviceId is required");
const args = [
path.join(scriptsDir, "ios-device-deploy.mjs"),
"--device",
deviceId,
];
if (skipAppexes) args.push("--skip-appexes");
if (skipBuild) args.push("--skip-build");
if (noLaunch) args.push("--no-launch");
if (bundleId) args.push("--bundle-id", bundleId);
return { cmd: "node", args };
}
/**
* Absolute node argv for the on-device BootCapture assertion. `--skip-build`
* is forced: deploy already built + installed the current tree, so the capture
* must reuse that install, never rebuild a second bundle. `--output` targets the
* run bundle's `smoke/` subdir so the assertion's attachments land inside the
* triage bundle.
*
* @param {{ scriptsDir: string, deviceId: string, outputDir: string,
* requireChat?: boolean, bundleId?: string | null }} opts
* @returns {{ cmd: string, args: string[] }}
*/
export function buildDeviceSmokeCommand({
scriptsDir,
deviceId,
outputDir,
requireChat = false,
bundleId = null,
}) {
if (!deviceId)
throw new Error("buildDeviceSmokeCommand: deviceId is required");
if (!outputDir)
throw new Error("buildDeviceSmokeCommand: outputDir is required");
const args = [
path.join(scriptsDir, "ios-device-capture.mjs"),
"--platform",
"device",
"--device",
deviceId,
"--skip-build",
"--output",
outputDir,
];
if (requireChat) args.push("--require-chat");
if (bundleId) args.push("--bundle-id", bundleId);
return { cmd: "node", args };
}
/**
* Absolute node argv for the boot-trace logs step. `--no-console
* --pull-boot-trace` is the ONLY engine-observability path on the full-Bun
* build: an attached `--console` launch SIGTRAPs the no-JIT engine host at load
* (#11515). `--output` writes the pulled trace into the bundle's `logs/` dir.
*
* @param {{ scriptsDir: string, deviceId: string, outputFile: string,
* bundleId?: string | null }} opts
* @returns {{ cmd: string, args: string[] }}
*/
export function buildDeviceLogsCommand({
scriptsDir,
deviceId,
outputFile,
bundleId = null,
}) {
if (!deviceId)
throw new Error("buildDeviceLogsCommand: deviceId is required");
if (!outputFile)
throw new Error("buildDeviceLogsCommand: outputFile is required");
const args = [
path.join(scriptsDir, "ios-device-logs.mjs"),
"--device",
deviceId,
"--no-console",
"--pull-boot-trace",
"--output",
outputFile,
];
if (bundleId) args.push("--bundle-id", bundleId);
return { cmd: "node", args };
}
/**
* Absolute argv for the physical-device screenshot used only after a lane step
* fails. Xcode's `devicectl` does not expose a screenshot subcommand on current
* runners, so this intentionally uses libimobiledevice's stable
* `idevicescreenshot` CLI when the host has it installed. The caller records a
* diagnostic artifact when the command is missing or the phone has no mounted
* developer disk image.
*
* @param {{ deviceUdid: string, outputFile: string }} opts
* @returns {{ cmd: string, args: string[], timeoutMs: number }}
*/
export function buildDeviceFailureScreenshotCommand({
deviceUdid,
outputFile,
}) {
if (!deviceUdid)
throw new Error(
"buildDeviceFailureScreenshotCommand: deviceUdid is required",
);
if (!outputFile)
throw new Error(
"buildDeviceFailureScreenshotCommand: outputFile is required",
);
return {
cmd: "idevicescreenshot",
args: ["--udid", deviceUdid, outputFile],
timeoutMs: 15_000,
};
}
/**
* Absolute node argv for the best-effort boot-trace pull used after a physical
* lane step fails. This reuses the supported `ios-device-logs.mjs` path rather
* than opening a debug console, because console attach kills the app on detach
* and SIGTRAPs full-Bun engine-host builds (#11515).
*
* @param {{ scriptsDir: string, deviceId: string, outputFile: string,
* bundleId?: string | null }} opts
* @returns {{ cmd: string, args: string[], timeoutMs: number }}
*/
export function buildDeviceFailureBootTraceCommand({
scriptsDir,
deviceId,
outputFile,
bundleId = null,
}) {
return {
...buildDeviceLogsCommand({
scriptsDir,
deviceId,
outputFile,
bundleId,
}),
timeoutMs: 45_000,
};
}