fix(ci): bound stalled Apple probes and record verified native APK
Android validation / emulator (35) (push) Failing after 4s
Android validation / emulator (37.0) (push) Failing after 9s
iOS validation / simulator (push) Failing after 1m5s
Android validation / build (push) Canceled after 2m0s

Mac Node bootstrap and checkout now pass, but Apple-tool preflight stalled after Xcode version output for twenty minutes. Add per-command deadlines and diagnostics without changing licenses/host settings; fourteen preflight/probe regressions pass. Record successful Android build/upload, downloaded APK signature/version and emulator install/launch, and unchanged missing-KVM matrix failures. No Apple app success is claimed.
This commit is contained in:
Yuvomi Mobile Contributors committed 2026-10-21 09:37:12 +02:00
1 parent 40a7962307
commit 92dbd0e06d
7 files changed
+120 -18

No files matched your search

+30 -4
View File
@@ -1,24 +1,32 @@
#!/usr/bin/env python3
"""Test runner prerequisite decisions with fake tools, not actual Apple SDKs."""
import os
import importlib.util
from pathlib import Path
import shlex
import subprocess
import sys
import tempfile
import unittest
SCRIPT = Path(__file__).with_name("check-ci-runner.sh")
SPEC = importlib.util.spec_from_file_location("apple_tools", SCRIPT.with_name("check-apple-tools.py"))
APPLE_TOOLS = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(APPLE_TOOLS)
class RunnerPrerequisiteTests(unittest.TestCase):
def run_check(self, mode, system="Linux", architecture="x86_64", missing=None, broken_xcode=False):
with tempfile.TemporaryDirectory(prefix="yuvomi-runner-test-") as temporary:
def run_check(self, mode, system="Linux", architecture="x86_64", missing=None, broken_xcode=False, broken_xcrun=False):
base = "/tmp/opencode" if Path("/tmp/opencode").exists() else None
with tempfile.TemporaryDirectory(prefix="yuvomi-runner-test-", dir=base) as temporary:
directory = Path(temporary)
for name in ["git", "curl", "unzip", "python3", "xcodebuild", "xcrun"]:
if name == missing:
continue
path = directory / name
status = 1 if name == "xcodebuild" and broken_xcode else 0
path.write_text(f"#!/bin/sh\nexit {status}\n")
status = 1 if (name == "xcodebuild" and broken_xcode or name == "xcrun" and broken_xcrun) else 0
path.write_text(f"#!/bin/sh\nexec {shlex.quote(sys.executable)} \"$@\"\n" if name == "python3"
else f"#!/bin/sh\nexit {status}\n")
path.chmod(0o700)
uname = directory / "uname"
uname.write_text('#!/bin/sh\ncase "$1" in -s) echo "$TEST_SYSTEM";; -m) echo "$TEST_ARCH";; esac\n')
@@ -62,6 +70,24 @@ class RunnerPrerequisiteTests(unittest.TestCase):
def test_unknown_mode_fails(self):
self.assertNotEqual(self.run_check("other").returncode, 0)
def test_missing_xcrun_is_actionable(self):
result = self.run_check("ios", system="Darwin", architecture="arm64", missing="xcrun")
self.assertNotEqual(result.returncode, 0)
self.assertIn("Cannot start xcrun", result.stderr)
def test_broken_xcrun_is_not_a_pass(self):
result = self.run_check("ios", system="Darwin", architecture="arm64", broken_xcrun=True)
self.assertNotEqual(result.returncode, 0)
self.assertIn("xcrun --find swift exited 1", result.stderr)
def test_unresponsive_apple_probe_times_out_with_guidance(self):
with self.assertRaisesRegex(RuntimeError, "interactive login session"):
APPLE_TOOLS.probe([sys.executable, "-c", "import time; time.sleep(30)"], timeout=0.05)
def test_apple_probe_preserves_tool_failure_diagnostic(self):
with self.assertRaisesRegex(RuntimeError, "fixture tool failure"):
APPLE_TOOLS.probe([sys.executable, "-c", "import sys; sys.exit('fixture tool failure')"])
if __name__ == "__main__":
unittest.main()