From 4d87288f2fb0877fe591dc41d1e18899efa14577 Mon Sep 17 00:00:00 2001 From: SuperDooper86 Date: Wed, 9 Sep 2026 23:56:02 +0200 Subject: [PATCH] ci: stage the Mac launch check on the internal volume --- scripts/smoke_test_api.py | 90 +++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 42 deletions(-) diff --git a/scripts/smoke_test_api.py b/scripts/smoke_test_api.py index c260255..e55cfc4 100644 --- a/scripts/smoke_test_api.py +++ b/scripts/smoke_test_api.py @@ -10,47 +10,53 @@ import urllib.error import urllib.request from pathlib import Path -app = Path(sys.argv[1]) / "Contents/MacOS/Meetingnotes" -with socket.socket() as listener: - listener.bind(("127.0.0.1", 0)) - port = listener.getsockname()[1] -with tempfile.TemporaryFile() as log: - process = subprocess.Popen( - [str(app), "-muteDeckAPIEnabled", "YES", "-muteDeckAPIPort", str(port), "-hasCompletedOnboarding", "YES", "-hasAcceptedTerms", "YES", "-SUEnableAutomaticChecks", "NO"], - stdout=log, stderr=subprocess.STDOUT, - ) - try: - for attempt in range(30): - if process.poll() is not None: - raise RuntimeError("CI app exited before the API became ready") - try: - with urllib.request.urlopen(f"http://127.0.0.1:{port}/api/info", timeout=2) as response: - info = json.load(response) - break - except (urllib.error.URLError, TimeoutError): - time.sleep(1) - else: - raise RuntimeError("CI API did not become ready") - assert info["name"] == "MeetingDebrief", "Unexpected API identity" +# Launch from the Mac's internal volume; the runner checkout is on removable storage. +cache = Path.home() / "Library/Caches/meetingnotes-ci" +cache.mkdir(parents=True, exist_ok=True) +with tempfile.TemporaryDirectory(prefix="smoke-", dir=cache) as directory: + staged = Path(directory) / "Meetingnotes.app" + subprocess.run(["ditto", sys.argv[1], str(staged)], check=True) + app = staged / "Contents/MacOS/Meetingnotes" + with socket.socket() as listener: + listener.bind(("127.0.0.1", 0)) + port = listener.getsockname()[1] + with tempfile.TemporaryFile() as log: + process = subprocess.Popen( + [str(app), "-muteDeckAPIEnabled", "YES", "-muteDeckAPIPort", str(port), "-hasCompletedOnboarding", "YES", "-hasAcceptedTerms", "YES", "-SUEnableAutomaticChecks", "NO"], + stdout=log, stderr=subprocess.STDOUT, + ) try: - urllib.request.urlopen(f"http://127.0.0.1:{port}/api/recording/status", timeout=2) - except urllib.error.HTTPError as error: - assert error.code == 401, f"Unexpected status: {error.code}" - else: - raise RuntimeError("Recording status allowed an unauthenticated request") - print("Local API readiness and authentication checks passed") - except Exception: - if process.poll() is None: - sample = subprocess.run(["sample", str(process.pid), "1", "1"], capture_output=True, text=True, timeout=10) - print(sample.stdout[:14000], file=sys.stderr) - log.seek(0) - print(log.read().decode(errors="replace")[-8000:], file=sys.stderr) - raise - finally: - if process.poll() is None: - process.terminate() + for attempt in range(30): + if process.poll() is not None: + raise RuntimeError("CI app exited before the API became ready") + try: + with urllib.request.urlopen(f"http://127.0.0.1:{port}/api/info", timeout=2) as response: + info = json.load(response) + break + except (urllib.error.URLError, TimeoutError): + time.sleep(1) + else: + raise RuntimeError("CI API did not become ready") + assert info["name"] == "MeetingDebrief", "Unexpected API identity" try: - process.wait(timeout=10) - except subprocess.TimeoutExpired: - process.kill() - process.wait() + urllib.request.urlopen(f"http://127.0.0.1:{port}/api/recording/status", timeout=2) + except urllib.error.HTTPError as error: + assert error.code == 401, f"Unexpected status: {error.code}" + else: + raise RuntimeError("Recording status allowed an unauthenticated request") + print("Local API readiness and authentication checks passed") + except Exception: + if process.poll() is None: + sample = subprocess.run(["sample", str(process.pid), "1", "1"], capture_output=True, text=True, timeout=10) + print(sample.stdout[:14000], file=sys.stderr) + log.seek(0) + print(log.read().decode(errors="replace")[-8000:], file=sys.stderr) + raise + finally: + if process.poll() is None: + process.terminate() + try: + process.wait(timeout=10) + except subprocess.TimeoutExpired: + process.kill() + process.wait()