fix: reliable auto-start and multi-instance connection support#1121
fix: reliable auto-start and multi-instance connection support#1121emiapwil wants to merge 32 commits into
Conversation
…o-beta-24972307282 chore: sync main (v9.6.8) into beta
Use ScreenCapture.CaptureScreenshotAsTexture() for game_view screenshots when include_image=true and in Play mode. This captures the final composited frame including UI Toolkit overlays, which camera.Render() misses since UI Toolkit renders at the compositor level after camera rendering. The camera-based path is still used when a specific camera is requested or when not in Play mode. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <[email protected]> Co-Authored-By: Happy <[email protected]>
PlayMode tests require entering play mode which triggers a domain reload. On large projects this can take >15s, causing the hardcoded 15s init timeout to auto-fail the test job before tests actually start. This adds an `init_timeout` parameter to `run_tests` that flows through the Python server → C# RunTests handler → TestJobManager. When set, the per-job timeout overrides the 15s default. The value is persisted across domain reloads via SessionState. Changes: - Python: Add `init_timeout` param to `run_tests()` function signature - C# RunTests: Read `initTimeout` param and pass to `StartJob()` - C# TestJobManager: Per-job `InitTimeoutMs` field with fallback to `DefaultInitializationTimeoutMs` (15s), persisted in SessionState Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Clamp initTimeoutMs in StartJob: negative values → 0, cap at 600s - Python: reject init_timeout <= 0 with explicit error before calling Unity - Add 3 C# EditMode tests for per-job InitTimeoutMs behavior (custom timeout, default timeout auto-fail, persist/restore) - Add 4 Python tests for init_timeout forwarding and validation Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Remove unused _originalJobs field - Add Assume.That guards for EditorApplication.isCompiling/isUpdating so the test is skipped (inconclusive) rather than producing misleading results when the editor is mid-compilation Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
The persist/restore test writes synthetic jobs to SessionState, which survives domain reloads and would be re-hydrated by TestJobManager's [InitializeOnLoadMethod] hook. Flush the cleaned in-memory state back to SessionState in TearDown so test artifacts don't leak across runs. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…it-timeout feat: Add configurable init_timeout for PlayMode test initialization
…eta.2-25116604754 chore: update Unity package to beta version 9.6.9-beta.2
…eta.3-25133350008 chore: update Unity package to beta version 9.6.9-beta.3
1.Add Compat based scripts revolving around UnityCompatShims.cs, that will document our current API Compatibility changes in several files. 2.Add custom screenshot folder selection
…on-compat-2026-04-27 Update0503
…eta.4-25294688169 chore: update Unity package to beta version 9.6.9-beta.4
…uitoolkit-screenshot-capture fix: include UI Toolkit overlays in game_view screenshots with include_image
…eta.5-25294857075 chore: update Unity package to beta version 9.6.9-beta.5
…v#1103) * fix: align CaptureComposited with renamed Project*-folder API PR CoplayDev#1040 added CaptureComposited referencing the old Assets-folder names (CaptureFromCameraToAssetsFolder, AssetsRelativePath) and called PrepareCaptureResult without the now-required folderOverride argument. Renames into the Project* equivalents; same fix at the call sites in ManageScene.cs. Closes CoplayDev#1100 Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * ci: gate releases on test success and trigger tests on PRs Beta-release was publishing to PyPI in parallel with Unity Tests, so broken commits could ship if Unity tests failed (as happened with CoplayDev#1100 on 9.6.9-beta.5). Make publish/version-bump jobs depend on the test jobs in both beta-release.yml and release.yml. The whole release halts before any irreversible commit/tag/push if either test job fails. Also extends the test workflows to fire on PRs so failures are caught before merge: - python-tests: pull_request trigger; runs on every PR (no secrets). - unity-tests: pull_request_target [labeled] trigger gated on the safe-to-test label and on the PR being from a fork. Maintainers apply the label after reviewing the diff; the workflow then runs with UNITY_LICENSE in scope against the PR head SHA. Re-pushed commits do NOT auto-trigger; maintainer must remove and re-apply the label to re-run after additional review. In-repo PRs continue to be tested via the existing push trigger, so no labeling friction for collaborator branches. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * fix(screenshot): propagate folderOverride to composited and specific-camera paths Two pre-existing inconsistencies surfaced by CodeRabbit on CoplayDev#1103: 1. CaptureComposited dropped the caller's output_folder by hardcoding folderOverride: null in PrepareCaptureResult and the camera fallbacks. Adds the parameter to CaptureComposited's signature and plumbs it through both fallback paths. 2. The targetCamera and includeImage-in-play paths in ManageScene's game_view screenshot did not resolve cmd.outputFolder, so a request that selected a specific camera would always write to the default folder. Resolve via ScreenshotPreferences.Resolve as the other paths already do, and gate AssetDatabase.ImportAsset on IsUnderAssets so non-Assets folders don't trigger a futile import. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * ci(unity-tests): harden pull_request_target and gate artifact upload Address CodeRabbit security review on CoplayDev#1103: - persist-credentials: false on the checkout step, so GITHUB_TOKEN is not written to disk and cannot be read by subsequent steps running PR-controlled code. - Explicit permissions: contents: read on the testAllModes job, scoping the workflow's token down from the default read/write set. - Skip upload-artifact when the main test step was skipped (e.g., because the preceding domain-reload step failed without continue-on-error). Avoids the noisy "No files were found" error on top of an already-failed run. The label-gated trigger plus these mitigations narrow the blast radius of the pull_request_target + checkout-PR-head pattern. The remaining trust boundary is the maintainer review before applying safe-to-test; documenting the review checklist (especially TestProjects/UnityMCPTests diffs) is a follow-up. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
…eta.6-25339361610 chore: update Unity package to beta version 9.6.9-beta.6
…ayDev#1106) The (Type, bool includeInactive) overload guarded its modern-API branch with #elif UNITY_2023_1_OR_NEWER while the legacy reflection helper LegacyFindObjectsOfType is gated by #if !UNITY_2022_3_OR_NEWER. That left the entire Unity 2022.3.x band falling through to a legacy helper that the preprocessor had already excluded, producing CS0103: 'LegacyFindObjectsOfType' does not exist in the current context (e.g. on 2022.3.62f2, see CoplayDev#1105). The 3-arg FindObjectsByType(Type, FindObjectsInactive, FindObjectsSortMode) overload has been available since Unity 2022.2, so 2022.3 can use the modern API directly. Aligning the threshold with the rest of the file (2022_3_OR_NEWER) closes the gap with no API loss. Closes CoplayDev#1105 Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
…layDev#1108) Both the push and pull_request_target paths filters listed MCPForUnity/Editor/** but not Runtime/, so a PR (or push) that modified only files under MCPForUnity/Runtime/** would not trigger Unity tests at all -- including the safe-to-test label flow on a fork PR. CodeRabbit flagged this as a Low/💤 nitpick on CoplayDev#1103; PR CoplayDev#1106 made it a concrete recurrence: applying safe-to-test had no effect because the Runtime-only diff was filtered out. Adding Runtime/** mirrors the asmdef layout (Editor and Runtime are the two assembly roots whose code can break Unity compilation), matches the codebase's "domain symmetry" convention, and closes the silent-skip path the label gate was designed to prevent. Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
…eta.7-25350517238 chore: update Unity package to beta version 9.6.9-beta.7
…connections - Remove #if UNITY_EDITOR_OSX guard from ExclusiveAddressUse in CreateConfiguredListener and IsPortAvailable - Add process ID to status heartbeat payload for multi-instance discovery - Write instance-specific status file (hash-pid.json) alongside project file - GetPortWithFallback now validates stored port availability before returning - Stop() cleans up both project and instance-specific status files - PortManager.SavePort includes PID and writes instance-scoped file
- HttpAutoStartHandler: use EditorApplication.update instead of delayCall to poll until EditorPrefs is initialized, fixing AutoStartOnLoad not being read during early editor startup - StdioBridgeHost: set ExclusiveAddressUse on all platforms (was macOS-only) to prevent SO_REUSEADDR port sharing on Linux; add PID to status heartbeat; write instance-scoped status file for multi-instance discovery - PortManager: set ExclusiveAddressUse on all platforms; GetPortWithFallback validates stored port availability before returning; add PID to PortConfig; write instance-scoped port files
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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 |
Summary
Fixes two fundamental reliability issues: (1) Unity MCP auto-start never fires on fresh editor launch because EditorPrefs is not initialized during [InitializeOnLoad], and (2) port sharing on Linux due to SO_REUSEADDR being the default, plus multi-instance discovery support.
Changes
HttpAutoStartHandler.cs
StdioBridgeHost.cs
PortManager.cs