Skip to content

fix(mobile): track-player RN 0.79 compat + fmt consteval for Xcode 26#14397

Open
raymondjacobson wants to merge 2 commits into
mainfrom
rj-mobile-release-retry-4
Open

fix(mobile): track-player RN 0.79 compat + fmt consteval for Xcode 26#14397
raymondjacobson wants to merge 2 commits into
mainfrom
rj-mobile-release-retry-4

Conversation

@raymondjacobson
Copy link
Copy Markdown
Member

Summary

#14396 unblocked the runner + hermesc issues. The binary build matrix now actually compiles and surfaces two real upstream-library incompatibilities with React Native 0.79 + Xcode 26 in run 26320122339.

1. Android RC + Prod — `react-native-track-player@4.0.1` is incompatible with RN 0.79

Kotlin compile error at `react-native-track-player` against the updated `HeadlessJsTaskService` in RN 0.79:

```
e: file://.../react-native-track-player/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt:764:5
'onBind' overrides nothing.
```

RN 0.79's `HeadlessJsTaskService.kt:58` now declares:

```kotlin
override fun onBind(intent: Intent): IBinder? = null
```

but `react-native-track-player@4.0.1` still has the pre-0.79 signature:

```kotlin
override fun onBind(intent: Intent?): IBinder
```

Kotlin allows covariant return types but not contravariant parameter types — `Intent?` ≠ `Intent` for override matching, so the compiler errors. `react-native-track-player@4.1.2` already matches RN 0.79's signature, so bumping the dep is the fix.

  • `packages/mobile/package.json`: `4.0.1` → `4.1.2`
  • `package-lock.json` regenerated to match.

2. iOS RC + Prod — `fmt 11.0.2` consteval fails under Xcode 26 / Apple Clang

xcodebuild archive failed compiling the `fmt` Pod:

```
Pods/fmt/include/fmt/format-inl.h:59: error: call to consteval function
'fmt::basic_format_string<...>' is not a constant expression
59 | fmt::format_to(it, FMT_STRING("{}{}"), message, SEP);
```

RN 0.79 pins fmt 11.0.2 via `third-party-podspecs/fmt.podspec`. Apple Clang in Xcode 26 enforces stricter `consteval` evaluation than 11.0.2 was written against. Fixed upstream in fmt 11.1+ (RN 0.80 picks up the newer fmt); for 0.79 the standard workaround is `-DFMT_USE_CONSTEVAL=0`, which falls back to the constexpr implementation.

Add a Podfile post_install hook that injects `FMT_USE_CONSTEVAL=0` into `GCC_PREPROCESSOR_DEFINITIONS` for the `fmt` target only. CI's existing `bundle exec pod install` step picks up the change with no lockfile churn.

Re-trigger the release flow

  • `packages/mobile/package.json`: `1.5.183` → `1.5.184`
  • iOS `Info.plist` `CFBundleShortVersionString`: `1.1.196` → `1.1.197`
  • Android `versionName`: `1.1.532` → `1.1.533`

Test plan

  • Merge → version-check fires all 4 binary jobs
  • Android RC + Prod pass Kotlin compile and reach `fastlane releaseCandidate` / `prod` (no `onBind overrides nothing`)
  • iOS RC + Prod compile `fmt` cleanly under Xcode 26 (no `consteval` error) and reach `pilot`
  • Slack notifications fire on success

🤖 Generated with Claude Code

raymondjacobson and others added 2 commits May 22, 2026 18:39
Two real failures surfaced in run 26319345276 after the displayer fix
in #14394 made fastlane log altool errors again:

### iOS RC + Prod — Apple now requires iOS 26 SDK

altool 409 Validation failed:

  This app was built with the iOS 18.5 SDK. All iOS and iPadOS apps
  must be built with the iOS 26 SDK or later, included in Xcode 26
  or later, in order to be uploaded to App Store Connect or submitted
  for distribution. (ID: 287c542e-…)

The `macos-15` runners default to Xcode 16.4 (iOS 18.5 SDK). Switch
both iOS upload jobs to `macos-26` (Tahoe, GA), which has Xcode 26
as the only supported major.

### Android RC + Prod — hermesc location anchored at the wrong root

  Couldn't determine Hermesc location. Please set `react.hermesCommand`
  to the path of the hermesc binary file.
  node_modules/react-native/sdks/hermesc/%OS-BIN%/hermesc

The previous PR restored `react.root` to its default
(`../..` = `packages/mobile`) to fix the Hermes JS bundle's entryFile
lookup. The same plugin uses `root` to detect the prebuilt hermesc
binary (PathUtils.kt#detectOSAwareHermesCommand) and only checks
`root/node_modules/react-native/sdks/hermesc/...`. Since RN is
hoisted to the monorepo node_modules, that lookup fails.

Set `react.hermesCommand` explicitly to the hoisted prebuilt path:

  $rootDir/../../../node_modules/react-native/sdks/hermesc/%OS-BIN%/hermesc

The `%OS-BIN%` placeholder is substituted at runtime by the plugin
to `linux64-bin` / `osx-bin` / `win64-bin` as appropriate. Verified
those bin directories exist in node_modules/react-native/sdks/hermesc/
in this branch.

### Housekeeping

- `Gemfile.lock` dependency line aligned to `= 2.234.0` to match the
  Gemfile pin from #14394 (the squash-merge left the lock at the
  pre-pin `>= 2.228.0` constraint).
- Bump versions to re-fire the build matrix:
  `1.5.182 -> 1.5.183`, iOS `1.1.195 -> 1.1.196`, Android `1.1.531
  -> 1.1.532`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
After #14396 the Hermesc + Xcode 26 runner fixes both worked. The
binary build matrix now actually compiles, and surfaced two remaining
upstream-library incompatibilities with React Native 0.79 + Xcode 26.

### Android RC + Prod — react-native-track-player onBind signature

Kotlin compile failed on the bundled `react-native-track-player`:

  e: .../trackplayer/service/MusicService.kt:764:5
     'onBind' overrides nothing.

RN 0.79's HeadlessJsTaskService now declares:
  override fun onBind(intent: Intent): IBinder? = null
                            ^^^^^^         ^^^^^^^^^^

react-native-track-player 4.0.1 still has the old signature:
  override fun onBind(intent: Intent?): IBinder
                            ^^^^^^^         ^^^^^^^

Kotlin parameter types must match the override exactly (return types
can be covariant, parameter types cannot). 4.1.2 already matches
RN 0.79's signature, so bumping the dep is the fix.

  packages/mobile/package.json: 4.0.1 -> 4.1.2
  package-lock.json regenerated.

### iOS RC + Prod — fmt consteval error under Xcode 26 / Apple Clang

xcodebuild archive failed on the fmt Pod:

  Pods/fmt/include/fmt/format-inl.h:59: error: call to consteval
  function 'fmt::basic_format_string<...>' is not a constant expression
     59 |   fmt::format_to(it, FMT_STRING("{}{}"), message, SEP);

RN 0.79 pins fmt 11.0.2 via third-party-podspecs/fmt.podspec. Apple
Clang in Xcode 26 enforces stricter consteval evaluation than the
version 11.0.2 was written against. Fixed upstream in fmt 11.1+ (RN
0.80 picks up the newer fmt); for 0.79 the workaround is to define
FMT_USE_CONSTEVAL=0 on the fmt target, falling back to the constexpr
implementation.

Add a Podfile post_install hook that injects the define for the fmt
target only. CI's existing `bundle exec pod install` step will pick
up the change without lockfile churn.

### Re-trigger the release flow
- packages/mobile/package.json: 1.5.183 -> 1.5.184
- iOS Info.plist CFBundleShortVersionString: 1.1.196 -> 1.1.197
- Android versionName: 1.1.532 -> 1.1.533

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 23, 2026

⚠️ No Changeset found

Latest commit: 5c33422

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant