Skip to content

chore(ci): run AI integration tests on Xcode 27 - #16899

Draft
andrewheard wants to merge 2 commits into
mainfrom
ah/ai-xcode-27-integration-ci
Draft

andrewheard wants to merge 2 commits into
mainfrom
ah/ai-xcode-27-integration-ci

Conversation

@andrewheard

@andrewheard andrewheard commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Runs the Firebase AI Logic test app integration tests on Xcode 27 for PRs, while nightly runs continue to cover the oldest supported Xcode (26.2). Together, the PR and nightly runs exercise the integration tests across a wide range of environments, and the jobs that gate PRs take advantage of Xcode 27's improved retry handling for parameterized Swift Testing tests.

Motivation

The integration tests call live backends and run with -retry-tests-on-failure -test-iterations 3 (see scripts/build.sh) to absorb transient network and backend flakiness. Most of them (44 of 53 @Tests) are parameterized Swift Testing tests, e.g., @Test(arguments: InstanceConfig.defaultConfigs), which run one test case per backend and API configuration.

Before Xcode 27, retrying a failed Swift Testing test reran the entire test plan, so a single flaky test case caused every integration test to run again. That made retries slow, used extra backend quota, and gave other tests another chance to flake. The Xcode 27 release notes (Testing > Resolved Issues) include fixes for this:

  • Fixed: The ‘Test Repetition Mode’ setting now only repeats individual Swift Testing test cases, rather than repeating the entire test plan. (130508488)
  • Fixed: The test link for a parameterized Swift Testing test case now includes a hash of the test’s arguments, allowing individual argument cases of the same test to be uniquely identified. (181841349)

With Xcode 27, only the failing test case (a single argument of a parameterized test) is retried. Running the PR-gating jobs on Xcode 27 makes retries faster and more targeted without reducing coverage.

Integration tests for the oldest supported Xcode version still run nightly, so regressions specific to older toolchains are still caught.

Changes

All AI integration tests now run as entries of a single testapp-integration matrix job:

Check PR Nightly (schedule)
testapp-integration (xcode-26-build) / (xcode-26-test) macos-15 / Xcode 26.2, build-for-testing macos-15 / Xcode 26.2, standard integration tests
testapp-integration (standard) xcode-27 / Xcode 27.0 xcode-27 / Xcode 27.0
testapp-integration (live) xcode-27 / Xcode 27.0 xcode-27 / Xcode 27.0
testapp-integration (gemini-language-model) xcode-27 / Xcode 27.0 xcode-27 / Xcode 27.0
  • Xcode 26 entry: Renamed the build matrix entry so its name reflects what it does: xcode-26-build on PRs (compile-only check against the oldest supported Xcode) and xcode-26-test in nightly runs (runs the standard integration tests). It previously only built for testing.
  • Standard and Live: Moved from macos-26 / Xcode 26.2 to xcode-27 / Xcode 27.0. This also removes the stale "Bump to 26.4" TODOs.
  • GeminiLanguageModel: Now blocking (removed continue-on-error: true). Also removed the GEMINI_LANGUAGE_MODEL environment variable: feat(ai): document and expose GeminiLanguageModel #16631 removed the Package.swift check that read it, and GeminiLanguageModel is now included unconditionally on Swift 6.4+ toolchains.
  • Consolidation: With continue-on-error and GEMINI_LANGUAGE_MODEL gone, the testapp-integration-live and testapp-integration-gemini-language-model jobs were identical to testapp-integration apart from their test filter, so they're now live and gemini-language-model matrix entries (about 45 fewer lines of YAML). Each matrix entry still runs on its own runner, so Live tests stay isolated from the other suites (fix(ci): isolate AI Live integration test runs #16493).
  • Test diagnostics: scripts/build.sh now passes -collect-test-diagnostics never to the AI integration test run, as fix(ci): skip test diagnostics collection in SPM test runs #16781 did for SPM test runs. On Xcode 27, xcodebuild runs simctl diagnose after a test attempt fails, which can stall for up to 10 minutes. With -retry-tests-on-failure, a single transient failure could otherwise trigger that stall in the now-blocking Xcode 27 jobs.
  • Hardening: The integration test step now passes matrix values through env instead of interpolating them directly into the run script, which avoids zizmor template-injection findings now that some matrix values are expressions.
  • Artifacts: Failure log artifacts are named after the matrix entry (e.g., xcodebuild-standard-…, xcodebuild-xcode-26-build-…). The Live and GeminiLanguageModel artifact names are unchanged.

Intentionally omitted on Xcode 26

  • Live tests run only on Xcode 27, which keeps them isolated in their own matrix entry (fix(ci): isolate AI Live integration test runs #16493) without adding another nightly runner.
  • GeminiLanguageModel tests require Swift 6.4+ and FoundationModels, so they're compiled out on Xcode 26 and are explicitly excluded there.

Environment coverage

Between PRs and nightly runs, the integration tests now cover:

  • Oldest supported Xcode: Xcode 26.2 on macOS 15 (built on every PR, tested nightly).
  • Latest Xcode: Xcode 27.0 (standard, Live, and GeminiLanguageModel tests on every PR and nightly).
  • Backends and API configurations: every parameterized test runs once per InstanceConfig.defaultConfigs entry in each environment above.

This is in addition to the SPM unit tests in _spm.yml, which continue to run on macos-15 / Xcode 26.2, macos-26 / Xcode 26.4, and xcode-27 / Xcode 27.0 across all platforms.

Notes for reviewers

  • Check names change: testapp-integration (build) → testapp-integration (xcode-26-build), testapp-integration-live → testapp-integration (live), and testapp-integration-gemini-language-model → testapp-integration (gemini-language-model). testapp-integration (standard) keeps its name.
  • The first nightly run will be the first time the full integration tests run on the macos-15 image (previously it only built for testing there).
  • The xcode-27 SPM unit test legs in _spm.yml remain non-blocking (continue-on-error), while the xcode-27 integration test jobs are now blocking.

#no-changelog

Run the standard, Live and GeminiLanguageModel integration tests
exclusively on the xcode-27 runner with Xcode 27.0. Previously, the
standard and Live tests ran on macos-26 with Xcode 26.2 and the
GeminiLanguageModel tests were non-blocking.

Rename the `build` matrix entry to `xcode-26-build` on PRs and
`xcode-26-test` in nightly runs. It still uses macos-15 with Xcode
26.2, the oldest supported version, but now runs the standard
integration tests nightly instead of only building for testing. Live
and GeminiLanguageModel tests are intentionally omitted on Xcode 26.

Also:
- Make the GeminiLanguageModel job blocking.
- Pass matrix values to the test step via `env` to avoid template
  injection.
- Remove the unused `GEMINI_LANGUAGE_MODEL` environment variable.
@gemini-code-assist

Copy link
Copy Markdown
Contributor
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Move the Live and GeminiLanguageModel integration test jobs into the
`testapp-integration` matrix as `live` and `gemini-language-model`.
Since both jobs now run on xcode-27 as blocking checks, they were
identical to `testapp-integration` apart from their test filter. Each
matrix entry still runs on its own runner, so Live tests stay
isolated from the other suites (#16493).

Also:
- Remove the `GEMINI_LANGUAGE_MODEL` environment variable, which is
  no longer read since #16631.
- Name failure log artifacts after the matrix entry and drop the
  `log_prefix` matrix key.
- Skip test diagnostics collection in AI integration test runs, as
  in #16781, since `simctl diagnose` can stall for up to 10 minutes
  on Xcode 27 after a failed test attempt.
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

This pull request optimizes the Firebase AI Logic integration test suite by migrating primary test execution to Xcode 27. By utilizing Xcode 27's enhanced test repetition logic, the CI pipeline can now target specific failing test cases rather than re-running entire test plans, significantly reducing execution time and backend resource usage. The changes also consolidate various test jobs into a unified matrix and improve security by hardening CI script execution.

Highlights

  • Xcode 27 Integration: Updated CI workflows to run AI integration tests on Xcode 27, leveraging improved retry handling for parameterized Swift Testing tests.
  • Test Consolidation: Consolidated multiple integration test jobs into a single matrix, simplifying the YAML configuration and improving maintainability.
  • Test Diagnostics: Disabled test diagnostics collection in build scripts to prevent long stalls during retries on Xcode 27.
  • Security Hardening: Updated CI scripts to pass matrix values through environment variables, preventing potential template injection vulnerabilities.
New Features

🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/sdk.ai.yml
Activity
  • Pull request created by andrewheard.
  • Gemini Code Assist bot provided usage instructions.
  • Author requested a summary of the pull request.

@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 updates the build script 'scripts/build.sh' to include 'spm_test_flags' when running tests for the 'FirebaseAITestApp-SPM' scheme. There are no review comments, and I have no additional feedback to provide.

This branch has not been deployed

No deployments
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