From 1810f9aa7c6230ce8b9858c3370f87233189c2f5 Mon Sep 17 00:00:00 2001 From: Chris Izatt Date: Thu, 18 Jun 2026 20:30:28 +0100 Subject: [PATCH 1/2] ci(ios): add iOS lane pinned to Xcode 26.0 / Swift 6.2 (matches ship toolchain) iOS gate: macos-26 runner (for the iOS 26 SDK that `.glassEffect` needs), with Xcode pinned to 26.0 (Swift 6.2) so CI matches the toolchain the app actually ships with. The runner default (Xcode 26.5 / Swift 6.3.2) rejects region- isolation `sending` diagnostics as errors that local Swift 6.2.4 accepts, so an unpinned lane fails on latent concurrency debt, not real regressions. A pre-pin `ls /Applications/Xcode*.app` prints the runner's available Xcodes (fallback to Swift-5 language mode if 26.0 isn't present). Runs `swift test` on TaskWraithKit + an unsigned simulator build of the app target. Follow-up (tracked): clear the Swift-6.3 region-isolation debt in RemoteSessionModel before bumping the pin. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/ci.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 066c4772..5132bc6b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,6 +50,40 @@ jobs: swift --version npm run test:swift:bridge + # iOS companion gate — the Electron matrix can't see iOS regressions, and the + # phone is the monetized launch surface. macOS 26 runner for the iOS 26 SDK + # (TaskWraithUI uses `.glassEffect`), with Xcode PINNED to 26.0 (Swift 6.2) to + # MATCH the shipping toolchain: the runner's default Xcode 26.5 (Swift 6.3.2) + # enforces region-isolation `sending` diagnostics as errors that local + # Swift 6.2.4 does not, so an unpinned lane would fail on latent concurrency + # debt rather than real regressions. (TODO: clear that Swift-6.3 region- + # isolation debt in RemoteSessionModel before bumping the pin.) + ios: + name: iOS (Kit tests + app build) + runs-on: macos-26 + steps: + - uses: actions/checkout@v4 + - name: Available Xcodes (pre-pin diagnostic) + run: ls -d /Applications/Xcode*.app + - name: Select Xcode 26.0 (Swift 6.2 — matches ship toolchain) + uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: "26.0" + - name: Toolchain versions + run: xcodebuild -version && swift --version + - name: Swift package tests (TaskWraithKit) + run: swift test --package-path ios/TaskWraithKit + - name: Generate Xcode project (XcodeGen) + run: | + brew install xcodegen + cd ios/TaskWraithApp && xcodegen generate + - name: Build app target (iOS Simulator, unsigned) + run: | + xcodebuild -project ios/TaskWraithApp/TaskWraith.xcodeproj \ + -scheme TaskWraith \ + -destination 'generic/platform=iOS Simulator' \ + build CODE_SIGNING_ALLOWED=NO + notarized-macos-release: name: Notarized macOS Release runs-on: macos-15 From 9289183f8684e64ea6004def1f5884fbc87e619b Mon Sep 17 00:00:00 2001 From: Chris Izatt Date: Thu, 18 Jun 2026 20:40:18 +0100 Subject: [PATCH 2/2] ci(ios): drop app-target xcodebuild (pinned Xcode lacks iOS platform); keep swift test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First pinned run: Xcode 26.0.1 selected fine and `swift test` PASSED (Kit + UI compile + 73 tests green on the ship Swift 6.2). Only the app-target xcodebuild failed — the pinned older Xcode has no iOS 26 simulator platform installed (GitHub pre-installs it only for the default Xcode 26.5), and -downloadPlatform would cost minutes+GBs per run for a thin wrapper. swift test already compiles all the SwiftUI/Glass code + runs the tests, so it's the real gate. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/ci.yml | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5132bc6b..5f4f0901 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,7 +59,7 @@ jobs: # debt rather than real regressions. (TODO: clear that Swift-6.3 region- # isolation debt in RemoteSessionModel before bumping the pin.) ios: - name: iOS (Kit tests + app build) + name: iOS (Kit tests) runs-on: macos-26 steps: - uses: actions/checkout@v4 @@ -71,18 +71,14 @@ jobs: xcode-version: "26.0" - name: Toolchain versions run: xcodebuild -version && swift --version + # `swift test` builds TaskWraithKit + TaskWraithUI (all the SwiftUI/Glass + # code) for the host and runs the 73 unit tests — the real regression + # gate. An app-target `xcodebuild` is intentionally NOT run here: the + # pinned Xcode 26.0 lacks the iOS simulator PLATFORM (GitHub pre-installs + # it only for the runner's default Xcode 26.5), and `-downloadPlatform iOS` + # would add minutes + GBs per run just to compile the thin app wrapper. - name: Swift package tests (TaskWraithKit) run: swift test --package-path ios/TaskWraithKit - - name: Generate Xcode project (XcodeGen) - run: | - brew install xcodegen - cd ios/TaskWraithApp && xcodegen generate - - name: Build app target (iOS Simulator, unsigned) - run: | - xcodebuild -project ios/TaskWraithApp/TaskWraith.xcodeproj \ - -scheme TaskWraith \ - -destination 'generic/platform=iOS Simulator' \ - build CODE_SIGNING_ALLOWED=NO notarized-macos-release: name: Notarized macOS Release