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
225 lines
7.6 KiB
JavaScript
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,
|
|
};
|
|
}
|