ci: build and test on Xcode 27 / Swift 6.4 - #27
Merged
Merged
Conversation
The package defaults its isolation to MainActor, so UIFontExtensions became MainActor-isolated while PinwheelFontProvider is deliberately nonisolated and Sendable — Swift 6.4 rejects the call where earlier compilers allowed it, and the Demo target stopped building. UIFont+Pinwheel.swift beside it was already nonisolated; these are descriptor math with no shared state, so they are too. Tests: unit 213/213 + hosted 16/16 green (local xcodebuild)
SwiftUI's FixedRoundedRect carried `cornerSize: CGSize` through iOS 26 and carries `radii: Radii` from iOS 27, so reading only cornerSize returned nil on 27: a card lost its radius and its radius token, and a pill whose radius went missing took the rasterizing path, dissolving the SALE badge's capsule and leaving white text on a light card. Read either, and answer nil for an `.uneven` radii rather than inventing a single corner for it. Guarded by the three tests this went red on: CaptureFidelityTests' testCardKeepsItsRadiusToken and testCornerAndSpacingReferenceDesignTokens, and SalePillCaptureTests' testSalePillFillSurvivesCapture. Tests: unit 213/213 + hosted 16/16 green (local xcodebuild)
Tests: unit 213/213 + hosted 16/16 green (local xcodebuild)
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.
CI now runs on the same toolchain as local: the
xcode-27runner image withXcode_27.0.app(Swift 6.4), replacingmacos-15/ Xcode 26.3. Pinwheel did not work on Xcode 27 before this, so two real fixes came with it.The Demo target stopped compiling. The package defaults its isolation to
MainActor, which madeUIFontExtensionsMainActor-isolated — butPinwheelFontProvideris deliberatelynonisolatedandSendable, and Swift 6.4 rejects that call where earlier compilers allowed it.UIFont+Pinwheel.swiftsitting beside it was alreadynonisolated; these helpers are descriptor math with no shared state, so they are too.Three capture tests went red, and the cause is one field. SwiftUI's private
FixedRoundedRectcarriedcornerSize: CGSizethrough iOS 26 and carriesradii: Radiifrom iOS 27. Reading onlycornerSizereturned nil on 27, so a card lost its radius and its radius token — and worse, a pill whose radius went missing took the rasterizing path, which dissolved the SALE badge's capsule and left white text on a light card. The engine now reads whichever field the OS supplies, and answers nil for an.unevenradii rather than inventing a single corner for it. Reading both keeps iOS 18-26 working.A throwaway probe dumping
Path.storagefound it; it left with the fix.Verified on Xcode 27.0 (27A266a) from a worktree, on an iOS 27 simulator: unit 213/213, hosted 16/16, and the warnings gate's own build clean of first-party warnings.
Actions is still paused, and this does not change that. The pause had two reasons — a runner-only crash in hostless XCTest, and scarce Actions minutes. I dispatched this workflow manually on the branch to see whether the new image fixes the first one; the second is a cost call that is yours. The triggers stay commented out and the local green-commit gate stays as it is.