Skip to content

ci(iroh): make direct-only release gate deterministic - #8489

Merged
azooz2003-bit merged 4 commits into
mainfrom
feat-iroh-direct-gate
Jul 19, 2026
Merged

azooz2003-bit merged 4 commits into
mainfrom
feat-iroh-direct-gate

Conversation

@azooz2003-bit

@azooz2003-bit azooz2003-bit commented Jul 19, 2026 •

Copy link
Copy Markdown
Collaborator

Root cause

The direct-only matrix leg reused the physical-device identity-only app attach policy while disabling relays. That left a headless runner dependent on nondeterministic LAN discovery to obtain a dialable address, so the Mac never published a route even though direct Iroh transport itself was healthy.

Fix

  • Keep automatic and relay-only on the full staging Mac-to-Simulator RPC gate.
  • Route direct-only to a credential-free isolated Simulator transport proof.
  • Bind two real Iroh endpoints with the shipped direct-only options, require relays disabled, verify both EndpointIDs, round-trip a bidirectional stream, and reject any relay-selected path.
  • Keep the direct test bounded and emit a separate redacted schema 3 verdict.
  • Skip app-only build dependencies and staging credentials for the direct-only job.

The first commit adds the failing dispatch regression test. The second adds the implementation.

Verification

  • node --test scripts/lib/mobile-attach.test.mjs, 29 passed
  • swift test --filter CmxIrohDirectTransportGateTests, passed on macOS
  • scripts/run-iroh-release-gate.sh --mode direct-only --tag irdir, passed in a fresh isolated iOS Simulator
  • bash syntax, workflow YAML parse, and git diff checks passed

View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Summary by cubic

Make the direct-only Iroh release gate deterministic by running a relay-disabled two-endpoint transport proof inside an isolated iOS Simulator. The gate now also fails if the test run is empty or has any failures.

  • Bug Fixes
    • Added CmxIrohDirectTransportGateTests to bind two real Iroh endpoints, disable relays, verify EndpointIDs, round-trip a bidirectional stream, require a direct/private path, bound timeouts, and never construct cmux TCP transport.
    • Added scripts/run-iroh-direct-transport-gate.sh to boot a fresh Simulator, run the suite via xcodebuild, emit a redacted schema 3 report, and reject empty or failing runs.
    • Updated scripts/run-iroh-release-gate.sh to route direct-only to the simulator transport proof, add --print-plan, and pass through --skip-build/--keep-simulator/--report-output; a Node test verifies mode-to-plan mapping.
    • CI: always ensure an iOS Simulator runtime and tolerate device drift by selecting an available iPhone device; skip app build deps and staging credentials for direct-only.

Written for commit ee96ad2. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added an iOS Simulator–based “direct-transport” validation flow for release gating.
    • Added release-gate plan preview via --print-plan, including a direct-only option that runs the direct-transport path.
  • Bug Fixes

    • Improved release-gate orchestration so iOS Simulator runtime availability is ensured regardless of mode, while build/staging steps remain skipped for direct-only.
  • Tests

    • Added a new direct-transport gate test covering relay-disabled behavior and direct/private path selection.
    • Added coverage for verifying --print-plan output across multiple modes.

@coderabbitai

coderabbitai Bot commented Jul 19, 2026 •

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 50387dad-10c0-4be4-a0b1-53c5cb736c7c

📥 Commits

Reviewing files that changed from the base of the PR and between 717fcd3 and ee96ad2.

📒 Files selected for processing (5)
  • .github/workflows/iroh-release-gate.yml
  • Packages/Shared/CmuxIrohTransport/Tests/CmuxIrohTransportTests/CmxIrohDirectTransportGateTests.swift
  • scripts/lib/mobile-attach.test.mjs
  • scripts/run-iroh-direct-transport-gate.sh
  • scripts/run-iroh-release-gate.sh

📝 Walkthrough

Walkthrough

Adds a direct-only Iroh release gate that runs focused iOS simulator transport tests, verifies bidirectional non-relay communication, reports results, and adjusts workflow setup and plan-selection tests.

Changes

Iroh direct transport release gate

Layer / File(s) Summary
Release gate routing and plan selection
scripts/run-iroh-release-gate.sh, scripts/lib/mobile-attach.test.mjs
Adds --print-plan, maps direct-only to the simulator direct-transport gate, forwards gate options, and tests supported mode mappings.
Simulator direct transport execution
scripts/run-iroh-direct-transport-gate.sh, Packages/Shared/CmuxIrohTransport/Tests/CmuxIrohTransportTests/CmxIrohDirectTransportGateTests.swift
Creates and boots an iOS simulator, runs the focused transport suite, verifies bidirectional traffic and direct/private path selection, validates results, emits JSON, and cleans up.
Workflow preparation for direct-only mode
.github/workflows/iroh-release-gate.yml
Ensures the iOS runtime independently while skipping app dependencies and staging account materialization in direct-only mode.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ReleaseGate
  participant DirectGate
  participant Xcodebuild
  participant TransportTests
  ReleaseGate->>DirectGate: Dispatch direct-only gate
  DirectGate->>Xcodebuild: Run focused simulator tests
  Xcodebuild->>TransportTests: Execute direct transport suite
  TransportTests->>TransportTests: Exchange request and response payloads
  TransportTests-->>DirectGate: Return direct-path test result
  DirectGate-->>ReleaseGate: Emit JSON report
Loading

Possibly related PRs

Suggested reviewers: lawrencecchen

🚥 Pre-merge checks | ✅ 25
✅ Passed checks (25 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Actor Isolation ✅ Passed Diff is test-only; the new serialized suite uses existing actor/sendable transport abstractions and adds no MainActor/UI/store isolation debt.
Cmux Swift Blocking Runtime ✅ Passed PASS: The only Swift file added is a test suite, and its bounded 20s/50ms sleeps and polling are test-only scaffolding allowed by the rule.
Cmux Browser Automation Off-Main ✅ Passed PR only changes scripts/run-iroh-direct-transport-gate.sh; no browser.* automation commands or policy files in scope of the rule were touched.
Cmux Expensive Synchronous Load ✅ Passed PR only adds a test Swift file plus scripts/workflow changes; no production Swift code moved any expensive synchronous load onto an interactive path.
Cmux Cache Substitution Correctness ✅ Passed No production Swift/TS/JS cache-swap change exists here; the only JS/Swift edits are tests, and the rest are bash/workflow updates.
Cmux No Hacky Sleeps ✅ Passed The new shell script adds bounded timeouts and event-based waits, but no fixed sleeps, polling loops, or delay-based race papering.
Cmux Algorithmic Complexity ✅ Passed The new shell logic does only one-off scans/sorts over simulator runtimes/device types and a small PID set; no nested rescans or user-scale collections.
Cmux Swift Concurrency ✅ Passed Actual diff only changes a shell script; the Swift test uses async/await and TaskGroup, with no Dispatch/Combine/completion-handler patterns.
Cmux Swift @Concurrent ✅ Passed The added Swift test helpers are not @MainActor/UI-bound and introduce no nonisolated async work needing @concurrent, so the rule is not violated.
Cmux Swift Package Boundaries ✅ Passed Diff only adds a test under Packages/Shared/CmuxIrohTransport/Tests and no app-target production Swift logic; boundary rule explicitly allows test code.
Cmux Swiftpm Lockfiles ✅ Passed PR changes only workflow/scripts/tests; no Package.swift, Package.resolved, xcodeproj, or cmux .gitignore changes, and the policy checker reports OK.
Cmux Swift Logging ✅ Passed PASS — the current diff changes only a shell script; the Swift test file has no print/debugPrint/dump/NSLog/Logger calls.
Cmux User-Facing Error Privacy ✅ Passed New CLI errors and report output are generic/redacted; no secrets, raw upstream messages, or prohibited implementation details are exposed.
Cmux Full Internationalization ✅ Passed Only an internal release-gate shell script changed; no user-facing Swift/web copy, catalogs, or locale files were added or modified.
Cmux Swiftui State Layout ✅ Passed No SwiftUI views/state were introduced; the only Swift change is a test file with no ObservableObject, GeometryReader, lazy-row stores, or render-time mutation.
Cmux Architecture Rethink ✅ Passed PASS: The only Swift change is a new test suite; its sleeps/polling are test-only synchronization, and no shared-state owners or lifecycle wiring were introduced.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR only adds a test fixture plus scripts/workflow changes; no user-visible NSWindow/NSPanel/WindowGroup code or cmuxAuxiliaryWindowIdentifiers edits appear.
Cmux Source Artifacts ✅ Passed The only changed path is a hand-written shell script; no generated logs, caches, DerivedData, or artifact directories were added to source control.
Cmux No Test Or Debug Seam In Production Source ✅ Passed Only scripts/run-iroh-direct-transport-gate.sh changed; no Swift production Sources files were touched, so no new debug/test seam was introduced.
Cmux No Ambient Global State ✅ Passed Only changed Swift file is a test suite under Tests/, and it uses nested private helpers only—no new top-level mutable globals or singletons.
Title check ✅ Passed The title concisely summarizes the main change: making the direct-only release gate deterministic.
Description check ✅ Passed The description covers the root cause, fix, and verification, though it doesn't follow the template headings exactly.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-iroh-direct-gate

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 19, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR makes the direct-only Iroh release-gate matrix leg deterministic by routing it to a credential-free, relay-disabled two-endpoint transport proof inside a fresh iOS Simulator instead of relying on nondeterministic LAN discovery on a headless runner.

  • CI workflow: direct-only now skips the zig/GhosttyKit app-build step and the staging-account materialization step, and adds a standalone Ensure iOS Simulator runtime step that runs unconditionally for all modes.
  • run-iroh-release-gate.sh: Adds --print-plan for mode-to-plan introspection, routes direct-only to the new run-iroh-direct-transport-gate.sh via exec, fixes the isAvailable Python default from True to False, and expands the preferred device name list to include iPhone 15 and 14 so CI images without iPhone 17/16 are self-healing.
  • run-iroh-direct-transport-gate.sh: New script that boots a fresh simulator, runs CmxIrohDirectTransportGateTests under xcodebuild, validates the xcresulttool summary for zero failures and non-empty test count, then emits a schema 3 redacted verdict.
  • CmxIrohDirectTransportGateTests.swift: New XCTest suite binding two real Iroh endpoints with directOnly transport verification mode, asserting relay URL is absent, verifying authenticated endpoint identities, exercising a bidirectional stream round-trip, and confirming the observed selected path is direct or privateNetwork.

Confidence Score: 5/5

Safe to merge — the change is entirely additive CI and test infrastructure with no modifications to production Swift sources.

All changed files are CI workflow YAML, shell scripts, and a test-only Swift file under Tests/. The root cause fix (LAN-discovery nondeterminism on headless runners) is correctly addressed by binding two real Iroh endpoints inside the simulator rather than relying on the app-attach flow. The isAvailable default and device-name expansion issues flagged in earlier review threads are both resolved here and in the new script. The simulator selection logic and xcresulttool validation are sound; cleanup traps correctly guard against dangling simulator state.

No files require special attention.

Important Files Changed

Filename Overview
.github/workflows/iroh-release-gate.yml Correctly separates simulator runtime download (all modes) from app build dependencies and staging credentials (skipped for direct-only); changes are well-gated on matrix.mode != 'direct-only'.
Packages/Shared/CmuxIrohTransport/Tests/CmuxIrohTransportTests/CmxIrohDirectTransportGateTests.swift New test-only XCTest suite under Tests/; uses bounded polling (ContinuousClock sleep with 10 s deadline) acceptable for test scaffolding; connectPair timeout uses a racing task group with defer { group.cancelAll() } so the timeout task is always cancelled on success; connection close ordering and error cleanup are correct.
scripts/run-iroh-direct-transport-gate.sh New script; isAvailable defaults to False (safe), preferred device list covers iPhone 14–17 with fallback to any startswith("iPhone") type, cleanup trap correctly skips deletion when SIMULATOR_ID is empty, boot uses a real bootstatus -b signal wrapped by run_with_timeout.py, and xcresulttool validation guards against empty or failing test runs before emitting the hardcoded schema 3 verdict.
scripts/run-iroh-release-gate.sh Adds --print-plan early-exit, routes direct-only to the new script via exec with a properly constructed argument array, fixes isAvailable default to False, and expands the preferred device list to match the new direct-transport script; all existing validation and cleanup logic is preserved.
scripts/lib/mobile-attach.test.mjs Adds a synchronous --print-plan node test that exercises all three modes; no sleeps or polling introduced.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[run-iroh-release-gate.sh] --> B{--mode}
    B -->|automatic| C[GATE_PLAN = app-rpc]
    B -->|relay-only| C
    B -->|direct-only| D[GATE_PLAN = simulator-direct-transport]

    C -->|--print-plan| E[print app-rpc and exit]
    D -->|--print-plan| F[print simulator-direct-transport and exit]

    C --> G[Full app-RPC gate]
    D --> H[exec run-iroh-direct-transport-gate.sh]
    H --> I[Create fresh iOS Simulator]
    I --> J[xcodebuild CmxIrohDirectTransportGateTests]
    J --> K{xcresulttool validation}
    K -->|fail| L[exit non-zero]
    K -->|pass| M[Emit schema 3 verdict]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[run-iroh-release-gate.sh] --> B{--mode}
    B -->|automatic| C[GATE_PLAN = app-rpc]
    B -->|relay-only| C
    B -->|direct-only| D[GATE_PLAN = simulator-direct-transport]

    C -->|--print-plan| E[print app-rpc and exit]
    D -->|--print-plan| F[print simulator-direct-transport and exit]

    C --> G[Full app-RPC gate]
    D --> H[exec run-iroh-direct-transport-gate.sh]
    H --> I[Create fresh iOS Simulator]
    I --> J[xcodebuild CmxIrohDirectTransportGateTests]
    J --> K{xcresulttool validation}
    K -->|fail| L[exit non-zero]
    K -->|pass| M[Emit schema 3 verdict]
Loading

Reviews (4): Last reviewed commit: "test(iroh): reject empty direct gate run..." | Re-trigger Greptile

Comment on lines +70 to +71
if runtime.get("isAvailable", True)
and runtime.get("identifier", "").startswith("com.apple.CoreSimulator.SimRuntime.iOS")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The isAvailable key defaults to True when absent, so a runtime entry that omits the field is treated as available. simctl list runtimes -j includes this key for all known entries, but a partially-downloaded or damaged runtime that omits the key would be picked as a candidate and then fail during xcodebuild. Defaulting to False (exclude if unknown) is safer.

Suggested change
if runtime.get("isAvailable", True)
and runtime.get("identifier", "").startswith("com.apple.CoreSimulator.SimRuntime.iOS")
if runtime.get("isAvailable", False)
and runtime.get("identifier", "").startswith("com.apple.CoreSimulator.SimRuntime.iOS")

Comment on lines +73 to +81
preferred_names = ("iPhone 17", "iPhone 16")
device_types = [
device for device in listing("devicetypes").get("devicetypes", [])
if device.get("name") in preferred_names
]
if not runtimes or not device_types:
raise SystemExit("no available iOS runtime or supported iPhone device type")
runtime = max(runtimes, key=version_key)
device = min(device_types, key=lambda value: preferred_names.index(value["name"]))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Hardcoded device names may miss available hardware types

preferred_names = ("iPhone 17", "iPhone 16") means any CI runner image that ships only iPhone 15 (or earlier) simulators produces the opaque error "no available iOS runtime or supported iPhone device type" even when a perfectly valid runtime is present. A simple fallback — e.g. filtering all device types whose name starts with "iPhone" when neither preferred name is present — would make the script self-healing against Xcode version drift without changing the preference ordering for modern runners.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/run-iroh-direct-transport-gate.sh`:
- Around line 94-125: Update the test execution flow in
scripts/run-iroh-direct-transport-gate.sh to configure and retain an xcodebuild
result bundle, then inspect it after xcodebuild completes and fail if it reports
zero executed tests. Perform this validation before constructing or writing
REPORT_JSON, so passed:true is emitted only after at least one matching test has
run.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f86a3865-6e18-421a-8867-ce72ce985d7d

📥 Commits

Reviewing files that changed from the base of the PR and between 11038e6 and 4a33b52.

📒 Files selected for processing (5)
  • .github/workflows/iroh-release-gate.yml
  • Packages/Shared/CmuxIrohTransport/Tests/CmuxIrohTransportTests/CmxIrohDirectTransportGateTests.swift
  • scripts/lib/mobile-attach.test.mjs
  • scripts/run-iroh-direct-transport-gate.sh
  • scripts/run-iroh-release-gate.sh

Comment thread scripts/run-iroh-direct-transport-gate.sh

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
scripts/run-iroh-direct-transport-gate.sh (1)

114-124: 🎯 Functional Correctness | 🔴 Critical | 🏗️ Heavy lift

Fail closed when no tests execute.

xcodebuild exits 0 even when zero tests match the -only-testing filter, meaning this script may silently emit a passed:true report without actually verifying the direct transport.

To guarantee that a test was executed, configure a result bundle and verify that the testsCount metric is greater than zero before writing REPORT_JSON.

🛠️ Proposed fix to validate test execution
 (
   cd "$REPO_ROOT/Packages/Shared/CmuxIrohTransport"
   python3 "$REPO_ROOT/scripts/ci/run_with_timeout.py" \
     --timeout-seconds 600 \
     -- xcodebuild \
       -scheme CmuxIrohTransport \
       -destination "platform=iOS Simulator,id=$SIMULATOR_ID" \
       -derivedDataPath "$DERIVED_DATA" \
+      -resultBundlePath "$DERIVED_DATA/ResultBundle.xcresult" \
       "$XCODEBUILD_ACTION" \
       -only-testing:CmuxIrohTransportTests/CmxIrohDirectTransportGateTests
 )
+
+TESTS_RUN=$(python3 -c '
+import json, subprocess, sys
+try:
+    out = subprocess.check_output(["xcrun", "xcresulttool", "get", "--path", sys.argv[1], "--format", "json"])
+    data = json.loads(out)
+    tests = sum(int(a.get("actionResult", {}).get("metrics", {}).get("testsCount", {}).get("_value", "0")) for a in data.get("actions", {}).get("_values", []))
+    print(tests)
+except Exception:
+    print("0")
+' "$DERIVED_DATA/ResultBundle.xcresult")
+
+if [[ "$TESTS_RUN" -eq 0 ]]; then
+  echo "error: xcodebuild executed 0 tests." >&2
+  exit 1
+fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/run-iroh-direct-transport-gate.sh` around lines 114 - 124, Update the
xcodebuild invocation in the direct transport gate to emit a result bundle, then
inspect its test-summary metrics and require testsCount to be greater than zero
before writing REPORT_JSON or reporting success. Fail closed with the existing
failure behavior when no tests execute, while preserving the current test filter
and build action.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/run-iroh-release-gate.sh`:
- Around line 117-142: Extract the duplicated Simulator selection logic into a
shared shell function in scripts/lib/mobile-attach.sh, preserving runtime
discovery, version selection, preferred iPhone ordering, fallback device-type
listing, and validation behavior. Replace the inline blocks in
scripts/run-iroh-release-gate.sh lines 117-142 and
scripts/run-iroh-direct-transport-gate.sh lines 70-96 with calls to the shared
helper, preserving each script’s existing use of the selected runtime and device
type.

---

Duplicate comments:
In `@scripts/run-iroh-direct-transport-gate.sh`:
- Around line 114-124: Update the xcodebuild invocation in the direct transport
gate to emit a result bundle, then inspect its test-summary metrics and require
testsCount to be greater than zero before writing REPORT_JSON or reporting
success. Fail closed with the existing failure behavior when no tests execute,
while preserving the current test filter and build action.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 07a8421c-bb93-44ae-948a-79c6857c779a

📥 Commits

Reviewing files that changed from the base of the PR and between 4a33b52 and 3c74e3d.

📒 Files selected for processing (2)
  • scripts/run-iroh-direct-transport-gate.sh
  • scripts/run-iroh-release-gate.sh

Comment on lines +117 to +142
if runtime.get("isAvailable", False)
and runtime.get("identifier", "").startswith("com.apple.CoreSimulator.SimRuntime.iOS")
]
device_types = [
device for device in listing("devicetypes").get("devicetypes", [])
if device.get("name") in ("iPhone 17", "iPhone 16")
]
if not runtimes or not device_types:
raise SystemExit("no available iOS runtime or supported iPhone device type")
if not runtimes:
raise SystemExit("no available iOS runtime")
runtime = max(runtimes, key=version_key)
preferred_names = (
"iPhone 17", "iPhone 17 Pro", "iPhone 16", "iPhone 16 Pro",
"iPhone 15", "iPhone 15 Pro", "iPhone 14", "iPhone 14 Pro",
)
preference = {name: index for index, name in enumerate(preferred_names)}
supported_device_types = runtime.get("supportedDeviceTypes")
if not isinstance(supported_device_types, list):
supported_device_types = listing("devicetypes").get("devicetypes", [])
device_types = sorted(
(
device for device in supported_device_types
if str(device.get("name", "")).startswith("iPhone")
),
key=lambda device: (
preference.get(str(device.get("name", "")), len(preference)),
str(device.get("name", "")),
),
)
if not device_types:
raise SystemExit("available iOS runtime has no supported iPhone device type")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract identical Simulator selection logic into a shared helper.

Both scripts contain an identical inline Python block used to discover an available iOS Simulator runtime and preferred iPhone device type. The shared root cause is duplicated environment-selection logic.

  • scripts/run-iroh-release-gate.sh#L117-L142: Extract this inline Python logic into a shared shell function (e.g., in scripts/lib/mobile-attach.sh, which is already sourced by both scripts).
  • scripts/run-iroh-direct-transport-gate.sh#L70-L96: Replace this inline Python block by invoking the new shared helper function.
📍 Affects 2 files
  • scripts/run-iroh-release-gate.sh#L117-L142 (this comment)
  • scripts/run-iroh-direct-transport-gate.sh#L70-L96
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/run-iroh-release-gate.sh` around lines 117 - 142, Extract the
duplicated Simulator selection logic into a shared shell function in
scripts/lib/mobile-attach.sh, preserving runtime discovery, version selection,
preferred iPhone ordering, fallback device-type listing, and validation
behavior. Replace the inline blocks in scripts/run-iroh-release-gate.sh lines
117-142 and scripts/run-iroh-direct-transport-gate.sh lines 70-96 with calls to
the shared helper, preserving each script’s existing use of the selected runtime
and device type.

@azooz2003-bit
azooz2003-bit force-pushed the feat-iroh-direct-gate branch from 717fcd3 to ee96ad2 Compare July 19, 2026 16:48
@azooz2003-bit
azooz2003-bit merged commit b5060bb into main Jul 19, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant