Repository navigation
ci: run E2E tests on the runner that built them - #14667
Conversation
|
Warning Review limit reachedNext included review available in 2 minutes. View limit detailsLimit details: You’ve used all 10 included reviews currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Repository: manaflow-ai/cmux/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (13)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
All contributors have signed the CLA ✍️ ✅ |
a2cc95a to
fb6843d
Compare
|
Found 1 test failure on Blacksmith runners: Failure
|
A test-e2e.yml run held two macOS runners in sequence. The build job compiled (or adopted) the app-host and UI test product and uploaded it; the test job then queued again for a runner of the same label, downloaded the product and ran the tests. With the macOS pools saturated that second queue took 10 to 60 minutes: run 36130355245's build finished at 12:14 and its test job sat queued until it was cancelled at 12:26. The test steps move into a composite action, .github/actions/e2e-run-tests, and the build job runs it right after it uploads the product, restoring from the archive it just packaged as compile admission does for its changed suites. The test job stays as the fallback, running only when the build job reports tested != 'true' (CI_E2E_TEST_IN_BUILD=0 hands the tests back to it). Both jobs check the action out at github.workflow_sha, so a dispatch of a ref older than the action still runs its tests. The app-host test environment (isolation, shard 1, xcresult capture) is exported by the action after the compile, wherever the tests run. The build job's timeout is twice job_timeout, since it now covers compiling and testing. The upload stays: later dispatches adopt it. Because the build job now ends after the tests, the sibling wait and cross-run reuse count an E2E producer as done once "Upload the compiled test product" succeeded, so a sibling does not wait out another run's tests, and a failing test no longer makes an intact product unadoptable. Guards that read the old test job's steps now read the action; the app-host home, pipe-capture and no-masking guards scan it too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main_regression_bisect.py classifies a probe run by its failed top-level step names, and the jobs API never lists a composite action's own steps. Both E2E jobs now name the action's step "Run selected tests", and a top-level "Resolve selectors against the built tests" step fails when the action recorded a selector that matched no built test. classify() checks that step first, since both fail together in that case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Run 36168944875 failed its screen-capture preflight, which skipped the tests' "Prepare isolated DerivedData". Their always() cleanup then found the build's canonical DerivedData path still in CMUX_DERIVED_DATA_PATH and refused it, adding a second error. The build's cleanup now hands the variable over empty once it has removed that DerivedData. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fb6843d to
d42b52a
Compare
|
Merge receipt for |
a1ac750 Predictive local echo for remote terminals (manaflow-ai#13967) e8e6a1a Split a single-argument tmux command string in __tmux-compat (manaflow-ai#14670) eb3f0b3 ci: reuse the resolve's manifests on the first scheme build (manaflow-ai#14674) 56a1d4e test(ci): check each iOS checkout step's ref, anchor job lookup (manaflow-ai#14676) 0a51482 docs: keep contributor agent docs free of internal machines and apps (manaflow-ai#14672) 64939a3 ci: count the org glaeda-minis runners in the live pool picker (manaflow-ai#14678) 18e7750 ci: run E2E tests on the runner that built them (manaflow-ai#14667) 20cda9e Merge pull request manaflow-ai#12956 from manaflow-ai/12938-orbstack-daemon-bootstrap 1ee8b22 Merge pull request manaflow-ai#12834 from manaflow-ai/issue-12791-sidebar-rendering-stalls 5b87c90 ci: bisect package test failures across main's history, with a skill (manaflow-ai#14533) ce2a516 ci: accept the hosted-runner cla.yml from manaflow-ai#14668 as the reviewed CLA base (manaflow-ai#14675) e142cac test: count the seed-retry checkouts in the iOS dispatch ref test (manaflow-ai#14671) 465ccf3 Merge branch 'main' of https://github.com/manaflow-ai/cmux into issue-12791-sidebar-rendering-stalls e5441eb fix: preserve sidebar cache app target wiring d4ca913 Merge branch 'main' of https://github.com/manaflow-ai/cmux into issue-12791-sidebar-rendering-stalls 5a30066 fix(cloud): import shared route policy 6d49c7f refactor(cloud): isolate private port route policy 1322537 style(ssh): format browser proxy regression harness 1d9676d test: align remote Git metadata with directory trust policy 3e8a382 Merge remote-tracking branch 'origin/main' into 12938-orbstack-daemon-bootstrap fbb338b fix(ssh): route browser identities through guest loopback da813a5 Wire AgentChatProseStreamWakeDriver.swift into the app target 5b4b943 Merge branch 'main' of https://github.com/manaflow-ai/cmux into issue-12791-sidebar-rendering-stalls 6a90db3 Merge branch 'main' of https://github.com/manaflow-ai/cmux into issue-12791-sidebar-rendering-stalls 91d432e ci: execute sidebar Git watcher regression tests c473752 test: keep sidebar regression on the standard run loop 45e344c merge: preserve import coordinator while syncing current main 260f261 fix(ssh): use portable chmod syntax for macOS carriers f90723f fix(ssh): keep stale projections out of Cloud image routing f8838da fix(ssh): preserve remote file drops and IPv6 loopback routes aea7e9d fix(ssh): carry remote loopback URLs through native browser routing cb7221b test(ssh): cover loopback port preview ownership 8806879 Merge remote-tracking branch 'origin/main' into 12938-orbstack-daemon-bootstrap 272453c fix(ssh): keep targeted reconnects scoped to their native viewer fe0a782 test(ssh): reject unrelated pane reconnects in native workspaces 6e15d80 fix(ssh): preserve main behavior and TUI arguments after package merge 940cd10 Merge latest origin/main for CI compatibility 768e434 Merge latest origin/main into SSH TUI migration c40ab2d chore(ssh): retain authentication localization entries 21db702 Merge concurrent SSH compatibility fixes aee57ba fix: preserve compatible local SSH uploads without a companion target 6ee35b4 test: retain local SSH bootstrap for unsupported companion targets 41924e0 Merge origin/main into SSH TUI migration 7fe5fa8 Merge remote-tracking branch 'origin/12938-orbstack-daemon-bootstrap' into issue-13648-ssh-workspace-selection bccce36 test: verify managed SSH respawn with runtime ownership checks a37d876 Merge origin/main into SSH TUI migration 1136940 test: request UUID output for managed SSH runtime harness 2232f0a fix: aggregate native and legacy SSH session listings 7d42c80 test: retain legacy dispatch when no native SSH workspaces exist 0ff7f62 fix: localize shared SSH authentication errors 6feb176 fix: honor SSH profiles for provider-created terminals afc61cb test: cover SSH provider default command and profile b3d7cbf test(ssh): serialize shared catalog lifecycle fixtures 295dbf5 fix(ssh): replace native remote workloads through their TUI provider 6ce447c test(ssh): require provider-backed respawn with stable surface identity 460a007 test(ssh): identify Linux workload owners by executable path ebb223b fix(ssh): lint loopback proxy policy plumbing f8bf123 Merge remote-tracking branch 'origin/12938-orbstack-daemon-bootstrap' into 12938-orbstack-daemon-bootstrap 18ac212 fix(ssh): thread loopback permission through proxy handlers 590dff5 Merge remote-tracking branch 'origin/main' into issue-13648-ssh-workspace-selection 7bd65e8 Merge remote-tracking branch 'origin/12938-orbstack-daemon-bootstrap' into issue-13648-ssh-workspace-selection d4b16de fix(ssh): fail closed before native remote respawn reaches local exec ac59a10 test(ssh): reject local respawn of native remote projections d999e65 fix(ssh): treat TUI projections as remote image targets 5967c75 fix(ssh): route native agent forks through cmux-tui providers f9c6797 test(ssh): prevent native agent forks from creating local terminals 3f684bf Merge remote-tracking branch 'origin/12938-orbstack-daemon-bootstrap' into issue-13648-ssh-workspace-selection cd0f1f4 style(ssh): format browser proxy regression test 20a1198 fix: bundle the published TUI client matching tagged source inputs fe4f257 fix(ssh): allow authenticated loopback browser proxy routes b05aa3e Merge remote-tracking branch 'origin/main' into 12938-orbstack-daemon-bootstrap c2ba696 fix(ssh): share terminal catalog metadata and link routing 15656d0 test: keep direct ownership probe separate from detached tmux control 88ebcfe Merge remote-tracking branch 'origin/12938-orbstack-daemon-bootstrap' into issue-13648-ssh-workspace-selection be56208 test: measure hidden SSH reads and renderer presentation across selection 553cdd0 fix: classify native SSH projections through their authoritative owner 00750ab test: classify restored native SSH terminals as remote 365a6eb test: support isolated jump-host SSH selection fixtures 67b9fe3 Merge remote-tracking branch 'origin/12938-orbstack-daemon-bootstrap' into issue-13648-ssh-workspace-selection 0b14eb0 Merge branch '12938-orbstack-daemon-bootstrap' of https://github.com/manaflow-ai/cmux into issue-13648-ssh-workspace-selection c2ce009 fix: preserve session and SSH options in managed TUI links 5e8bf78 test: preserve managed SSH session identity in TUI link launch 3983f4c test: require cmux-tui ownership across managed SSH selection 460950d Merge branch 'main' of https://github.com/manaflow-ai/cmux into issue-12791-sidebar-rendering-stalls ec6a650 Merge branch 'main' of https://github.com/manaflow-ai/cmux into issue-12791-sidebar-rendering-stalls 634509f Merge branch 'main' of https://github.com/manaflow-ai/cmux into issue-12791-sidebar-rendering-stalls a71b3dc fix: retain initial sidebar snapshot observation 414e47f chore: normalize merged source whitespace 6734ee9 merge: sync latest main 264c7da test: pump common run loop modes for sidebar harness 8662152 Merge branch 'main' of https://github.com/manaflow-ai/cmux into issue-12791-sidebar-rendering-stalls d386ce0 Merge branch 'main' of https://github.com/manaflow-ai/cmux into issue-12791-sidebar-rendering-stalls 13d30fa Merge branch 'main' of https://github.com/manaflow-ai/cmux into issue-12791-sidebar-rendering-stalls 4092d91 Merge branch 'main' of https://github.com/manaflow-ai/cmux into issue-12791-sidebar-rendering-stalls de85594 fix: handle blank browser import identifiers fa8e093 Merge branch 'main' of https://github.com/manaflow-ai/cmux into issue-12791-sidebar-rendering-stalls 1d9afef fix: instantiate browser destination resolver adapter 110d737 fix: expose Foundation UUID in browser resolver API 4d4c8ea refactor: move browser destination resolution into CmuxBrowser a73b116 merge origin/main into issue-12791-sidebar-rendering-stalls 4a6a7df test: isolate shared watcher lifecycle fixture 511d198 fix: import process identity from CmuxFoundation 683ca09 fix: close browser import review findings c9de46c merge origin/main into issue-12791-sidebar-rendering-stalls bb48a38 test: inject browser import coordinator in wizard coverage 3ee91b2 fix: preserve watcher on failed discovery and browser automation contracts d790f65 test: reproduce installed watcher loss on descriptor failure 642c86a fix: scope browser import automation helper f9f67f4 merge origin/main into issue-12791-sidebar-rendering-stalls 79e6a1a fix: continue issue 12791 rendering stall repairs 9ee3bb1 test: preserve Git metadata monitoring when watcher replacement fails 0bffb5f fix: construct sidebar snapshots only at lifecycle and event boundaries 2e683ce test: import Cloud fixture remote configuration from its owning module 8d16430 Merge remote-tracking branch 'origin/main' into issue-12791-sidebar-rendering-stalls 50b7233 fix: restore pairing preparation recovery lost in upstream merge f165b33 test: split nested Cloud assertion to unblock hosted suites d5464d0 test: verify native callback lifetime through queued teardown ccfe1cd Merge remote-tracking branch 'origin/main' into issue-12791-sidebar-rendering-stalls ad3672a fix: retain the FSEvents receiver through native registration fee5924 fix: isolate sidebar discovery and bound workspace snapshot lifetime dbba283 test: reproduce sidebar snapshots surviving workspace replacement # Conflicts: # .github/workflows/ci-guards.yml # .github/workflows/ci-macos.yml # .github/workflows/ci.yml # .github/workflows/test-e2e.yml
An E2E dispatch used to queue for a macOS runner twice. The
buildjob compiled (or adopted) the app-host and UI test product and uploaded it. Then thetestjob queued again for a runner of the same label, downloaded the product and ran the tests. With the pools saturated, that second wait decided how long a run took. Across the 20 successful runs on 2026-09-25, thetestjob itself ran for 2–3 min. The ~11 runs from 09:19Z on then waited 1.3–96 min for its runner. Run 36130355245 finished its build at 12:14, and its test job was still queued when it was cancelled at 12:26.Now
buildruns the tests itself, on the runner that just built the product.Test steps move into a composite action. They live in
.github/actions/e2e-run-testsand cover the virtual display, ffmpeg and TCC, the capture preflight, bun and tmux, the product restore into aRUNNER_TEMPDerivedData, the app-host home, selector resolution, the test run, recording, uploads, the summary and cleanup. Thealways()upload and cleanup steps keep theirif:.Where the tests run:
buildruns the action after it uploads the product and cleans the canonical DerivedData. It restores from the archive it just packaged (CMUX_PRODUCT_FROM_PRODUCER, the same path compile admission uses for changed suites), so the tests run the exact uploaded bytes.teststays as the fallback. It runs only whenneeds.build.outputs.tested != 'true', andCI_E2E_TEST_IN_BUILD=0hands the tests back to it.Old refs still work. Both jobs sparse-check the action out at
github.workflow_shainto.e2e-workflow, so a dispatch (or bisect probe) of a ref older than the action still runs its tests. The scripts the action calls come from the tested revision, as before.Test environment. The action exports
CMUX_CI_APP_HOST_ISOLATION_REQUIRED=1,CMUX_APP_HOST_SHARD=1andCMUX_APP_HOST_CAPTURE_XCRESULTS=1after the compile, wherever the tests run.CMUX_CI_XCODE_APPis the build's own pin.Timeout.
build's timeout is2 × job_timeout, since it now covers compiling and testing. The filter job computes it and rejects a non-integer value.Product upload stays. Later dispatches adopt it. Since
buildnow ends after the tests,e2e_sibling_build.pyandreuse_app_host_products.pycount an E2E producer as done onceUpload the compiled test producthas succeeded. A sibling no longer waits out another run's tests, and a failing test no longer makes an intact product unadoptable.Bisect verdicts.
main_regression_bisect.pyreads a probe's verdict from failed top-level step names, and the jobs API doesn't list a composite's inner steps. So both jobs name the action stepRun selected tests, and a top-levelResolve selectors against the built testsstep fails when the action recorded an unresolvable selector.classify()now checks that step first.Cleanup after a skipped preparation. When the build job has removed its canonical DerivedData, it clears
CMUX_DERIVED_DATA_PATH. A failure that skips the tests' own preparation (a failed screen-capture preflight, as in run 36168944875) then leaves theiralways()cleanup nothing to refuse.Guard tests that read the old
testjob now read the action. The app-host home, pipe-capture and no-masking guards also scan composite actions, so the E2E steps can't drop out of their coverage silently.Known cost: the
Cache Swift packagespost-save only runs when the job succeeds, so a run whose tests fail no longer saves a SwiftPM cache miss. The E2E compilation cache is saved by an explicit step before the tests and is unaffected.Owned Macs: glaeda's runner hook gives test-e2e's
buildandtestjobs the unknown-job "compile" class, which never takes the mini's gui token. That was already true of the oldtestjob. The fix belongs in glaeda and is being done separately.Verification
linux-guardtests fromtests/test-execution.tomlran on this branch and on main at the same base. The results match, apart fromtest_swift_testing_suite_timeout.py, which failed on main and passed here.test_ci_e2e_compilation_cache.py::test_a_missing_manifest_fails_instead_of_silently_compiling(macOS bash 3.2,ONLY_TESTING[@]underset -u).continue-on-errorinside the action.4f0ac55da15:blacksmith-6vcpu-macos-26. There,buildqueued 2.1 min and ran 10.4 min: a 5.7 min compile, then a 0.8 min in-job test step. The product restore took 14 s.WindowTitleTemplateTestsexecuted 12 tests.testwas skipped, so no second macOS queue.require_selected_test_execution.shrightly rejects. That's the open Blacksmith activation problem (test-e2e lane: XCUITest activation fails on both default and warp runners (no logged-in GUI user) #8588, cmuxUITests that launch the app report false passes in CI (XCTExpectFailure swallows the launch abort) #9667), not this change.testjob fails the same way on these pools today (36124174448, 36125021766, 36124921773).Before and after, single-class runs. Across the 20 successful runs on 2026-09-25,
buildran 6–22 min.testran a further 2–3 min, most of it checkout, product download and restore, after a second queue of 1.3–96 min from 09:19Z onward. With this change there is one queue and one job. In the cmuxTests run above, the tests added 0.8 min tobuild, against the 2–3 min the oldtestjob spent. Per run, that saves about 2 macOS runner-minutes (the second checkout and download) and the entire second queue, which was the part that decided the wall time on saturated pools.— Quillmoor g1 🌊
🤖 Generated with Claude Code