Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,26 @@ 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
run: sudo xcode-select -s /Applications/Xcode_16.app
# 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
- name: Test core
run: swift test --enable-code-coverage
- name: Build app
run: |
xcodebuild \
-project TranscriberApp/TranscriberApp.xcodeproj \
-scheme TranscriberApp \
-project TranscriberApp/Scribe.xcodeproj \
-scheme Scribe \
-configuration Debug \
-destination 'platform=macOS' \
build \
Expand Down
13 changes: 11 additions & 2 deletions Sources/TranscriberCore/Calendar/CalendarWatcher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading