Skip to content

ci: require Xcode 26.2 as the minimum version - #1876

Merged
andrewheard merged 3 commits into
mainfrom
ah/ci-xcode-26
Oct 15, 2026
Merged

andrewheard merged 3 commits into
mainfrom
ah/ci-xcode-26

Conversation

@andrewheard

@andrewheard andrewheard commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Firebase now requires Xcode 26.2 or later. This PR moves the quickstart CI to Xcode 26.2 and removes Xcode 16 workarounds from the scripts and sample code.

Changes

Workflows (.github/workflows/)

  • Bumped matrix.xcode from 16.4 to 26.2 in abtesting, analytics, crashlytics, database, functions, performance and storage.
  • Changed the hardcoded Xcode_16.4.app path in authentication.yml to Xcode_26.2.app.
  • Added an xcode-select step to every job that was using the runner's default Xcode:
    • Matrix jobs (abtesting, crashlytics, database, functions, performance, storage): sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer
    • Single-Xcode jobs (config, database spm-buildonly, firestore, inappmessaging, installations, messaging, performance spm-buildonly): sudo xcode-select -s /Applications/Xcode_26.2.app/Contents/Developer

Important

The macOS-15 runner image still defaults to Xcode 16.4 (see toolset-15.json). Without an explicit xcode-select, bumping matrix.xcode would only change the job name, and the build would still use 16.4. scripts/test.sh doesn't switch Xcode itself.

Scripts (scripts/)

  • test.sh and build-for-testing.sh now exit with Unsupported Xcode version if Xcode is older than 26. The Xcode 16 branches are gone.
  • test.sh: replaced the sudo xcode-select -s block, which re-selected the Xcode that was already active, with xcode-select -p to match build-for-testing.sh. Xcode is now selected only in the workflows.
  • test.sh: removed the unused ios_version variable. The default device is still iPhone 17 Pro.
  • build-for-testing.sh: removed the unused iphone_version and DEVICE defaults. This script always builds for generic/platform=iOS.

Sample code

  • firebaseai/.../AudioController.swift: removed the #if compiler(<6.2) shim for AVAudioSession.CategoryOptions.allowBluetoothHFP. It was added in fix: Restore Xcode 16 testing for AI QS #1828 for Xcode 16, and Xcode 26.2 ships Swift 6.2 or later.

Downstream impact

The firebase-ios-sdk _quickstart.yml workflow runs this repo's scripts/test.sh on macos-26, after selecting Xcode 26.4 itself. It doesn't set OS or DEVICE, so it still gets the same default device (iPhone 17 Pro). I don't expect any change in behavior.

Testing

  • bash -n passes for scripts/test.sh and scripts/build-for-testing.sh.
  • All workflow files pass YAML validation.
  • CI is green on every workflow.

What to watch in CI

The macOS-15 jobs still use iPhone 16 simulators (and config.yml boots "iPhone 16"). The runner installs the iOS 26.2 simulator runtime with Xcode 26.2. firebaseai.yml already runs iPhone 16 with Xcode 26.2 on macos-15, so I expect these to work. If any job fails with "unable to find a destination", switch that job to an iPhone 17 model or add a xcodebuild -downloadPlatform iOS step.

Firebase now requires Xcode 26.2, so drop Xcode 16 support from CI,
scripts, and sample code.

- Bump the Xcode matrix and hardcoded paths from 16.4 to 26.2.
- Select Xcode explicitly in jobs that used the runner default. The
  macOS-15 runner defaults to Xcode 16.4, so the matrix bump alone
  only changed the job names.
- Make test.sh and build-for-testing.sh exit on Xcode < 26 and
  remove the Xcode 16 device defaults.
- Replace the no-op sudo xcode-select in test.sh with
  xcode-select -p, matching build-for-testing.sh.
- Remove the unused ios_version and DEVICE variables.
- Remove the Swift < 6.2 allowBluetoothHFP shim from
  AudioController.swift.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request simplifies Xcode version checks and device configuration across testing scripts, removing dynamic iPhone versioning in favor of a hardcoded "iPhone 17 Pro" default, and cleans up compiler-version-specific extensions in AudioController.swift. Feedback on scripts/test.sh highlights a potential crash due to an unbound variable error when OS is explicitly set but DEVICE is not, suggesting to decouple the defaulting of DEVICE from OS.

Comment thread scripts/test.sh
zizmor's unpinned-uses policy requires actions to be pinned to a
commit hash. Pin actions/checkout@master to v6.0.1, matching the
existing pins in firebaseai.yml and check.yml, and pin
actions/cache@v4 to v4.3.0, the commit v4 currently points to.
test.sh only defaulted DEVICE when OS was also unset, so running it
with OS=iOS and no DEVICE exited on an unbound variable under set -u.
Default DEVICE to iPhone 17 Pro whenever OS is iOS and DEVICE is
unset. Callers that set both or neither are unaffected.

Suggested in code review by gemini-code-assist.
@andrewheard
andrewheard requested a review from ncooke3 October 15, 2026 19:49
@andrewheard
andrewheard marked this pull request as ready for review October 15, 2026 19:55
@andrewheard
andrewheard merged commit 04a9eac into main Oct 15, 2026
49 checks passed
@andrewheard
andrewheard deleted the ah/ci-xcode-26 branch October 15, 2026 20:06
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.

2 participants