Skip to content

build: make iOS 26 the platform baseline - #1

Merged
weskcode merged 2 commits into
developfrom
feature/ios-26-baseline
Sep 2, 2026
Merged

weskcode merged 2 commits into
developfrom
feature/ios-26-baseline

Conversation

@weskcode

@weskcode weskcode commented Sep 1, 2026

Copy link
Copy Markdown
Owner

What changed

Makes iOS 26 the platform baseline, in three parts.

Deployment floor → iOS 26.0 / macOS 26.0. project.yml declares both, and the duplicate MACOSX_DEPLOYMENT_TARGET in settings.base is gone so options.deploymentTarget is the single source of truth. Every availability gate became unconditionally true, so LiquidGlassGroup.swift and ViewModifiers.swift now call the Liquid Glass API directly and their macOS/iOS arms collapse into one. No #available or @available checks remain in the codebase.

Floor is 26.0, not a point release: nothing in the app needs a 26.x point API, so a higher floor would delete the same code while supporting fewer devices.

Test runtime → iOS 26.5 or newer. Scripts/resolve-ios-simulator.sh takes a floor (CHEATSHEET_MIN_IOS_RUNTIME, default 26.5) and fails with a per-runtime breakdown rather than silently selecting an older runtime.

Contracts are now enforced, not assumed. Scripts/verify-build-sdk.sh asserts the toolchain SDK major so an Xcode beta cannot produce a beta-SDK submission build. Scripts/verify-project-config.sh asserts the deployment floors so a regression fails CI.

Two bugs found along the way

  • The simulator resolver matched device family on the display name. Four genuine iPhone simulators on iOS 26.5 are renamed (QR-floor-265, WoW-iOS26-verify, …) and were invisible to it. Masked today only because iOS 27.0 happens to be installed with stock-named devices; pinned to the 26 line, the pool would have gone empty with conforming devices sitting right there. Now matches on deviceTypeIdentifier.
  • Tie-breaking was arbitrary (lexicographic UDID), which selected a stale scratch device and failed a test run. Ranking now prefers stock-named devices, so the pick is reproducible.

CI

Moves to the macos-26 runner. A macOS 26 app cannot run on a macOS 15 host, so the macOS test job would not have launched. macos-26 (GA since Feb 2026, Xcode 26.6) also carries an SDK and simulator runtime satisfying both floors. Xcode selection now prefers a versioned Xcode_26* bundle but defers to the SDK check as the real gate, since a bundle name cannot guarantee an SDK version.

Verification

55 tests in 5 suites pass on both the iOS simulator and macOS; iOS Release builds clean; 0 warnings.

Not verified locally: the iOS 26 SDK is not installed on this machine (only Xcode 27 beta), so the build was compiled against the iOS 27 SDK with the 26.0 floor. CI remains the authority for the shipping SDK — please watch this PR's first run, particularly the macos-26 runner label and the 26.5 simulator floor.

🤖 Generated with Claude Code

weskcode and others added 2 commits September 1, 2026 11:14
Raise the deployment floor to iOS 26.0 / macOS 26.0, pin the test runtime
to iOS 26.5 or newer, and make both contracts enforceable rather than
assumed.

Deployment floor:
- project.yml declares iOS 26.0 and macOS 26.0, and drops the duplicate
  MACOSX_DEPLOYMENT_TARGET from settings.base so options.deploymentTarget
  is the single source of truth for the macOS floor.
- Every availability gate is now unconditionally true, so the Liquid Glass
  paths in LiquidGlassGroup.swift and ViewModifiers.swift call the API
  directly and the macOS/iOS arms collapse into one. No #available or
  @available checks remain in the codebase.
- 26.0 rather than a point release: nothing in the app needs a 26.x point
  API, so a higher floor would delete the same code and support fewer
  devices.

SDK contract:
- Scripts/verify-build-sdk.sh asserts the active toolchain's SDK major
  matches the branch contract (26), so a machine carrying an Xcode beta
  cannot silently produce a beta-SDK submission build. CI hard-fails;
  Scripts/verify-macos.sh warns, since developing on a beta is fine.

Test runtime:
- Scripts/resolve-ios-simulator.sh takes a minimum runtime (26.5 by
  default, CHEATSHEET_MIN_IOS_RUNTIME to override) and fails with a
  per-runtime breakdown rather than falling back below the floor. A green
  suite that ran on an unsupported runtime certifies nothing.
- It matches device family on deviceTypeIdentifier instead of the display
  name; renamed simulators were being skipped entirely. Ranking now
  prefers stock-named devices so the pick is reproducible.

Enforcement and CI:
- Scripts/verify-project-config.sh asserts the deployment floors, so a
  regression fails CI instead of shipping.
- CI moves to the macos-26 runner: a macOS 26 app cannot run on a macOS 15
  host, and macos-26 also carries an SDK and simulator runtime satisfying
  both floors. Xcode selection prefers a versioned Xcode 26 bundle but
  defers to the SDK check as the real gate, since a bundle name cannot
  guarantee an SDK version.

Docs/os-support-policy.md records the policy, the branching model for iOS
27 adoption, and the measured iOS 27 readiness result.

Verified locally: 55 tests in 5 suites pass on both the iOS simulator and
macOS, iOS Release builds clean, 0 warnings. The iOS 26 SDK itself is not
installed on this machine, so CI remains the authority for the shipping
SDK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
simctl keeps listing the iOS 27.0 beta runtime as available after switching
back to the release Xcode, so "newest wins" sent shipping test runs onto the
beta OS. Under Xcode 26.6 the resolver picked an iOS 27.0 iPhone rather than
the 26.5 one.

Exclude runtimes whose major exceeds the active simulator SDK. The toolchain
now sets the ceiling, so the iOS 27 readiness branch needs no special case:
selecting Xcode 27 raises it automatically. Major-level rather than exact, so
a 26.6 runtime under a 26.5 SDK stays usable.

Verified under Xcode 26.6 (SDK 26.5): the resolver returns the iOS 26.5
iPhone 17 Pro (9C915472), and the diagnostic marks 27.0 runtimes as newer
than the active SDK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@weskcode
weskcode merged commit f115dec into develop Sep 2, 2026
2 checks passed
@weskcode
weskcode deleted the feature/ios-26-baseline branch September 2, 2026 06:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant