Pin CI to Xcode 26.3 - #346
Open
Ryanmello07 wants to merge 1 commit into
Open
Conversation
CI has been compiling against the iOS 18 SDK while the app runs on iOS 26 devices. Anything that only exists, or only misbehaves, on the current SDK is invisible here, and that gap has started costing real time. Two cases from one week. App code merged to main needed an SDK symbol the 16.4 toolchain does not have, so it built green in CI and failed on a developer machine. And `ControlCenter` is absent from the macOS 15 SDK that 16.4 uses, which is the entire reason WidgetRefresh.reloadControl is walled off behind `#if os(iOS)` rather than shipping the Control Center toggle on macOS -- a workaround this bump makes unnecessary, though removing it is left to its own change. Still pinned to an exact path rather than to the image default or to "latest": the original pin's reasoning holds, only its target was stale. A runner-image bump must not move the toolchain, and with it the SDK the app is compiled against, without a commit that says so. 26.3 is the newest stable on the macos-15 image, which also carries 26.2, 26.1.1 and 26.0.1. Be clear about what this does NOT buy. The job builds and runs unit tests; it never launches the app, and `-only-testing:networkTests` excludes the ui tests entirely. A rendering fault that only appears on a current SDK still gets through -- one just did. Closing that needs the app actually run in CI, which is a separate and larger change. Two documents reasoned from the old pin and are corrected rather than left asserting something false, which is how the symbol-template constraint got lost the first time. The generated symbols stay at Template v6.0, but the reason changes: Xcode 26's actool would accept 7.0, so 6.0 is now kept for compatibility with anyone still on an Xcode 16 series rather than because CI rejects it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AWV4MaF9JBcQppSX9UxATa
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
CI compiles against the iOS 18 SDK while the app runs on iOS 26 devices. Anything that only exists — or only misbehaves — on the current SDK is invisible here, and that gap has started costing real time.
Two cases from one week:
mainneeded an SDK symbol the 16.4 toolchain doesn't have. It built green in CI and failed on a developer machine.ControlCenteris absent from the macOS 15 SDK that 16.4 uses. That is the entire reasonWidgetRefresh.reloadControlis walled off behind#if os(iOS)instead of shipping the Control Center toggle on macOS. This bump makes that workaround unnecessary — removing it is left to its own change.What changed
One line, plus the comment that explains it:
Still pinned to an exact path, not to the image default and not to "latest". The original pin's reasoning holds — a runner-image bump must not move the toolchain, and with it the SDK the app is compiled against, without a commit saying so. Only its target was stale.
26.3 is the newest stable on the
macos-15image, which also carries 26.2, 26.1.1 and 26.0.1 (16.4 remains the image default, which is why the explicit pin still matters). Simulator runtimes on that image include iOS 26.0–26.2, so the test step has a current runtime to run against.What this does NOT buy
Worth stating plainly so it isn't mistaken for more than it is. The job builds and runs unit tests; it never launches the app, and
-only-testing:networkTestsexcludes the UI tests entirely. A rendering fault that only appears on a current SDK still gets through — one just did, and no toolchain pin would have caught it. Closing that needs the app actually run in CI, which is a separate and larger change worth doing on its own merits.Docs corrected rather than left stale
Two places reasoned from the old pin. Leaving them asserting something false is exactly how the symbol-template constraint was lost the first time — a generator that documented a rule it no longer enforced everywhere.
The generated symbols stay at Template v6.0, but the reason changes. Xcode 26's
actoolwould accept 7.0, so the pin is no longer what enforces 6.0; it is now kept as the floor that anyone still on an Xcode 16 series can read. A 6.0 template renders identically on a neweractool, so there is nothing to gain by raising it.Verification
I cannot verify this locally — the only Xcode on this machine is 27, so I can't reproduce a 26.3 build. This PR's own CI run is the verification, which is the appropriate place for a CI change to prove itself.
Two things to expect from that run, so neither is misread:
mainis currently red there onTunnelNativeColdRestoreTests.swiftandTunnelAuthStartupContinuationTests.swift— pre-existing failures that only became visible once the asset-catalog error stopped aborting the build earlier. If this run fails the same way, the pin is fine and those tests are the separate problem.🤖 Generated with Claude Code
https://claude.ai/code/session_01AWV4MaF9JBcQppSX9UxATa