From 4f11b7cd5fc3cbebb176667f25f208cd6260a815 Mon Sep 17 00:00:00 2001 From: Szymon Sypniewicz Date: Mon, 11 May 2026 18:57:44 +0100 Subject: [PATCH 1/4] ci: select Xcode 26.3 to satisfy mlx-audio-swift Swift 6.2 requirement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pinned mlx-audio-swift dependency declares `// swift-tools-version:6.2`, which SwiftPM enforces on the consumer side. The previous CI step selected Xcode 16 (Swift 6.0), so every build since PR #1 has failed with: package 'mlx-audio-swift' is using Swift tools version 6.2.0 but the installed version is 6.0.0 The macos-15 runner image ships Xcode 26.3 at /Applications/Xcode_26.3.app alongside the default Xcode 16.4. No runner change needed — just point xcode-select at the newer toolchain. --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a64bb6b..9549f7b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,9 @@ jobs: steps: - uses: actions/checkout@v4 - name: Select Xcode - run: sudo xcode-select -s /Applications/Xcode_16.app + # mlx-audio-swift requires swift-tools-version:6.2, which ships with + # Xcode 26. The macos-15 image bundles Xcode 26.3 alongside Xcode 16. + run: sudo xcode-select -s /Applications/Xcode_26.3.app - name: Build core run: swift build - name: Test core From 31cba7a34aea0c2f0fb07f439ba67fc97f3e7d24 Mon Sep 17 00:00:00 2001 From: Szymon Sypniewicz Date: Mon, 11 May 2026 19:13:53 +0100 Subject: [PATCH 2/4] calendar: await poll-task termination in CalendarWatcher.stop CI on macos-15 surfaced testStopCancelsPollLoop as flaky: after `await watcher.stop()`, the lookup callout occasionally fired one more time before the poll task actually exited. Locally on faster hardware the in-flight refreshNow() completed before the test reached its second sleep so the bug stayed hidden. The real cause is the previous sync `stop()` returning before the already-resumed poll iteration finished. Refactoring `stop()` to be async and `await task?.value` ensures any drained refresh completes before stop returns, so the test's "no more polls after stop" invariant holds across hardware. All five existing call sites already prefix with `await` (actor isolation), so no caller signature changes. --- .../TranscriberCore/Calendar/CalendarWatcher.swift | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Sources/TranscriberCore/Calendar/CalendarWatcher.swift b/Sources/TranscriberCore/Calendar/CalendarWatcher.swift index ccc503a..793378e 100644 --- a/Sources/TranscriberCore/Calendar/CalendarWatcher.swift +++ b/Sources/TranscriberCore/Calendar/CalendarWatcher.swift @@ -68,9 +68,18 @@ public actor CalendarWatcher { } } - public func stop() { - pollTask?.cancel() + /// Cancels the poll loop and awaits its termination. The previous sync + /// variant returned before the in-flight `refreshNow()` had finished, so + /// `stop()` could complete and a stale poll iteration would still bump + /// the lookup callout afterward — visible on slower hardware as a + /// flaky `testStopCancelsPollLoop`. By awaiting `task.value` here, any + /// in-progress refresh is allowed to drain before `stop()` returns and + /// no further polls can happen for this watcher instance. + public func stop() async { + let task = pollTask pollTask = nil + task?.cancel() + await task?.value } /// Forces an immediate refresh outside the regular cadence. Called on From cc954926bb6c5401833a79c6d9d809060f3df861 Mon Sep 17 00:00:00 2001 From: Szymon Sypniewicz Date: Mon, 11 May 2026 19:20:43 +0100 Subject: [PATCH 3/4] ci: fix stale project + scheme names in Build app step MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The xcodebuild step still pointed at TranscriberApp/TranscriberApp.xcodeproj and scheme `TranscriberApp`, neither of which exist — the app project is `TranscriberApp/Scribe.xcodeproj` with scheme `Scribe`, per `scripts/dev-install.sh`. The previous compile failure masked this; once Build core and Test core started passing the Build app step exposed it. --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9549f7b..7d5e2f0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,8 +22,8 @@ jobs: - name: Build app run: | xcodebuild \ - -project TranscriberApp/TranscriberApp.xcodeproj \ - -scheme TranscriberApp \ + -project TranscriberApp/Scribe.xcodeproj \ + -scheme Scribe \ -configuration Debug \ -destination 'platform=macOS' \ build \ From 42a7bd3d799cfcfa310ae16c62b657c1ac8555cf Mon Sep 17 00:00:00 2001 From: Szymon Sypniewicz Date: Mon, 11 May 2026 19:35:42 +0100 Subject: [PATCH 4/4] ci: move job to macos-26 runner for Xcode 26 asset toolchain After fixing the Swift 6.2 toolchain selection, swift build and swift test passed on macos-15. The xcodebuild step then failed at CompileAssetCatalogVariant: Xcode 26's `actool` invokes ibtoold, which links AVFCore privately and dyld-fails on macOS 15 with missing CoreMedia symbols (`_kFigCaptionRegionDisplayAlign_Before`, `_kFigCaptionRegionDisplayAlign_After`). Xcode 26's tools need their matching OS frameworks; macos-26 is the supported runner image for that combination. --- .github/workflows/ci.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7d5e2f0..742dfa9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,12 +8,16 @@ on: jobs: test: - runs-on: macos-15 + # Needs macOS 26 host: Xcode 26's `actool` invokes AVFCore-backed + # `ibtoold` for `.icon` asset compilation, which dyld-fails on macOS 15 + # because of missing CoreMedia symbols (e.g. `_kFigCaptionRegionDisplayAlign_Before`). + # `swift build` and `swift test` worked on `macos-15` once xcode-select + # pointed at Xcode 26.3, but the app's asset catalog needs the OS frameworks. + runs-on: macos-26 steps: - uses: actions/checkout@v4 - name: Select Xcode - # mlx-audio-swift requires swift-tools-version:6.2, which ships with - # Xcode 26. The macos-15 image bundles Xcode 26.3 alongside Xcode 16. + # mlx-audio-swift requires swift-tools-version:6.2 (Xcode 26). run: sudo xcode-select -s /Applications/Xcode_26.3.app - name: Build core run: swift build