[0.81][iOS] Cache prebuilt iOS binaries in ~/Library/Caches/ReactNative#56842
Open
cipolleschi wants to merge 3070 commits into
Open
[0.81][iOS] Cache prebuilt iOS binaries in ~/Library/Caches/ReactNative#56842cipolleschi wants to merge 3070 commits into
cipolleschi wants to merge 3070 commits into
Conversation
…ion complete callback (#56459) Summary: Pull Request resolved: #56459 ## Changelog: [Internal] [Added] - Allow waiting for user land Animated animations before firing transition complete callback Instead of calling `onCompleteCallback` synchronously at the end of `startViewTransition`, defer it until all animations have finished. Since transition animation can be kicked off in user land from view transition event handlers, we need extra APIs to signal to native side when animation starts and finishes. This ensures the transition lifecycle properly waits for native animated transitions to complete. - Add `waitForTransitionAnimation` / `transitionAnimationFinished` to the delegate interface and expose via `NativeViewTransition` TurboModule - JS calls `waitForTransitionAnimation(animationId)` before starting each animation and `transitionAnimationFinished(animationId)` in the completion callback - `ViewTransitionModule` tracks pending animation IDs in a `std::set` and fires `onCompleteCallback_` only when all animations are done - only track and wait for animations started during transition-ready callback - if no animation requests to be waited for, resolve complete promise immediately when transition-ready callback finishes Reviewed By: sammy-SC Differential Revision: D99366980 fbshipit-source-id: 6313bdd2b3f7b90a5aee24e0faec905bce75d715
Summary: On Android 15 (API 35), edge-to-edge is enforced by default unless the app explicitly opts out via `windowOptOutEdgeToEdgeEnforcement`. On Android 16+, it's always enforced regardless. Previously, edge-to-edge behavior was only driven by the `edgeToEdgeEnabled` gradle property, meaning apps on Android 15+ could be in edge-to-edge mode without React Native being aware of it, leading to incorrect insets / layout behavior. This PR introduces `isEdgeToEdge`, a computed value that accounts for the OS-level enforcement in addition to the gradle flag, and replaces most usages of `isEdgeToEdgeFeatureFlagOn` with it. A new `initEdgeToEdge(context, flag)` function replaces `setEdgeToEdgeFeatureFlagOn()` and reads the theme attribute to detect opt-out on API 35. ## Changelog: [ANDROID] [FIXED] - Handle edge-to-edge when it's not enabled by the `edgeToEdgeEnabled` gradle property but enforced by the OS (Android 15+) Pull Request resolved: #56055 Test Plan: - Verify on Android 15 device/emulator **without** `edgeToEdgeEnabled = true`: `isEdgeToEdge` should be `true` (unless opted out via theme attribute). - Verify on Android 16+ device/emulator: `isEdgeToEdge` should always be `true`. - Verify on Android 14 and below without the flag: `isEdgeToEdge` should be `false`. - Verify with `edgeToEdgeEnabled = true`: behavior unchanged, `isEdgeToEdge` is `true` on all API levels. Reviewed By: javache Differential Revision: D100437440 fbshipit-source-id: 7cc826ccd2d1596121671eb456358f558e14299c
Summary:
`Modal` accepts a `style` prop via `ViewProps` (since `ModalProps` spreads `...ViewProps`) but silently discards it. The inner container `<View>` only applies `styles.container` and `containerStyles` (which handles `backdropColor`/`transparent`), so any style passed by the consumer has no effect.
For example, `<Modal style={{ padding: 20 }}>` compiles without errors but the padding is never applied.
This PR forwards `this.props.style` to the inner container View with a carefully designed precedence chain:
```
styles.container (layout defaults + white background)
→ this.props.style (consumer overrides)
→ containerStyles (explicit transparent / backdropColor always win)
```
`containerStyles` now only sets `backgroundColor` when `transparent` or `backdropColor` are explicitly passed, ensuring these Modal-specific API props always take precedence over the generic `style` prop while still allowing consumers to customize other style properties.
**Precedence examples:**
| Usage | Result |
|---|---|
| `<Modal style={{ backgroundColor: 'red' }}>` | Red (user overrides default white) |
| `<Modal transparent>` | Transparent (explicit prop wins) |
| `<Modal transparent style={{ backgroundColor: 'red' }}>` | Transparent wins |
| `<Modal backdropColor="blue" style={{ backgroundColor: 'red' }}>` | Blue wins |
| `<Modal style={{ padding: 20 }}>` | Works, no conflicts |
## Changelog:
[GENERAL] [FIXED] - Forward `style` prop to Modal's inner container View with correct precedence so consumer styles are applied without overriding `transparent` or `backdropColor`
Pull Request resolved: #56181
Test Plan:
1. Render a Modal with a custom style prop:
```jsx
<Modal visible style={{ padding: 40, backgroundColor: 'red' }}>
<View style={{ flex: 1, backgroundColor: 'white' }}>
<Text>Hello</Text>
</View>
</Modal>
```
2. **Before fix:** `padding` and `backgroundColor` are silently ignored
3. **After fix:** The modal container has 40px padding and a red background
Also verified that:
- `transparent={true}` always produces a transparent background, even if `style={{ backgroundColor }}` is set
- `backdropColor` always takes precedence over `style.backgroundColor`
- Default behavior (no `style` prop) is unchanged — white background
- Non-backgroundColor style properties (padding, margin, etc.) work without conflicts
Reviewed By: javache
Differential Revision: D101170804
Pulled By: zeyap
fbshipit-source-id: b138648ce41b55eb794c79a0217f905d5cc9a5f2
Summary: This PR introduces a `ExtraWindowEventListener` interface that allows native modules to be notified when new windows are created or destroyed (e.g. Modal dialogs). Third-party libraries can implement it, or emit window events through `ReactContext.onExtraWindowCreate` / `ReactContext.onExtraWindowDestroy`. This opens the door for libraries like `expo-navigation-bar` to build a proper `NavigationBar` module that stays in sync across all windows (including modals). ## Related issue - zoontek/react-native-navigation-bar#4 ## Changelog: [ANDROID] [ADDED] - Add `ExtraWindowEventListener` interface to allow native modules to react to window creation / destruction (e.g. Modal dialogs) Pull Request resolved: #55721 Test Plan: Follow #56059 test plan Reviewed By: cortinico Differential Revision: D94871845 Pulled By: alanleedev fbshipit-source-id: b2c00950c3c60dbeb3d53520d95160b301829a5e
Summary: ## Changelog: [Internal] [Fixed] - unbreak ViewTransition fantom tests this gets broken after my recent changes to viewtransition runtime Reviewed By: NickGerleman Differential Revision: D101224031 fbshipit-source-id: ecef6d4ea73635a6416a1febf9c44b9ecfef0f22
#55855) Summary: `KeyboardAvoidingView` has several issues on Android 15+ and when `edgeToEdgeEnabled` is set to `true` on Android < 15: 1. **Keyboard events relied on a legacy detection path for Android < 30** (`checkForKeyboardEventsLegacy`), which used height heuristics (`heightDiff > mMinKeyboardHeightDetected`) to guess whether the keyboard was visible. 2. **`keyboardDidHide` reported incorrect `screenY` values.** It used `mVisibleViewArea.height()`, which in edge-to-edge mode doesn't correspond to the actual screen bottom. 3. **`KeyboardAvoidingView` used `_onKeyboardChange` for `keyboardDidHide` on Android**, which stores the event instead of nullifying it. After keyboard dismissal, any subsequent `onLayout` would re-enter `_updateBottomIfNecessary` with stale coordinates, causing a render loop (especially visible with `behavior="height"` in edge-to-edge mode, where `frame.y` shifts slightly on each layout cycle). This PR: - Removes `checkForKeyboardEventsLegacy` and uses `WindowInsetsCompat` APIs (via AndroidX) - Fixes `keyboardDidHide` to report `screenY` as `mVisibleViewArea.bottom + barInsets.bottom` - Fixes the Android `keyboardDidHide` listener in `KeyboardAvoidingView` to use `_onKeyboardHide`, matching the iOS behavior and breaking the render loop. Closes #49759 ## Changelog: [ANDROID] [FIXED] - Fix `KeyboardAvoidingView` on Android 15+ / with `edgeToEdgeEnabled` Pull Request resolved: #55855 Test Plan: Tested with `rn-tester` KeyboardAvoidingView example on: - Android 16 (API 36) (edge-to-edge is enforced) - Android 14 (API 34) with `edgeToEdgeEnabled` set to `true` or `false` - Android 7 (API 24) with `edgeToEdgeEnabled` set to `true` or `false` For each, verified: - `behavior="padding"`: keyboard open/close adjusts padding correctly - `behavior="position"`: keyboard open/close translates content correctly - `behavior="height"`: keyboard open/close works without render loop or glitching - `keyboardDidShow` and `keyboardDidHide` events report correct coordinates Reviewed By: mdvacca Differential Revision: D100437445 Pulled By: alanleedev fbshipit-source-id: 23b89a4380d02a0f524d587f89d023d21782406c
…e possible (#56465) Summary: Pull Request resolved: #56465 The `cloneProps` function in `AnimationBackend.cpp` was using `std::move(*animatedProps.rawProps)` inside a `shadowTree.commit()` transaction lambda. Since commits can be retried (when `currentRevision_.number != oldRevision.number`), the moved-from `RawProps` would be in an unspecified state on the second attempt, leading to incorrect or undefined behavior. When `enableFabricCommitBranching` is enabled, commit retries are not a concern, so moving is safe. When disabled, we now copy via `RawProps(*animatedProps.rawProps)` instead. This is the only dangerous move in the animation backend commit path. The `AnimationBackendCommitHook` already copies correctly (`RawProps(*snapshot->rawProps)`), and `AnimatedPropsRegistry::getMap()` is safe because moved pending data persists in the `map` member across retries. Changelog: [General][Fixed] - Fix potential data corruption in animation backend when ShadowTree commits are retried by copying RawProps instead of moving them Reviewed By: zeyap Differential Revision: D101161363 fbshipit-source-id: 43b9277f37563098c8ba878777d7a3099bdf1373
Summary: Pull Request resolved: #56482 Changelog: [internal] `ReactNativeType` is the type of the legacy renderer, which is being removed. This removes the references to it so the removal can land without Flow errors. Reviewed By: zeyap Differential Revision: D101352959 fbshipit-source-id: 3425260a1604eb83998b32dd8c25d399eb6c6ee1
…ow (#36297) (#56483) Summary: Pull Request resolved: #56483 ## Summary PR #36285 deleted the Paper (legacy) renderer, including the shim file `scripts/rollup/shims/react-native/ReactNative.js`. However, the `runtime_commit_artifacts` workflow still tries to `rm` this file after moving build artifacts into `compiled-rn/`. Since the file no longer exists in the build output, `rm` (without `-f`) fails and kills the entire step. This has caused **every run of the Commit Artifacts workflow to fail since #36285 landed on April 16**, blocking both `builds/facebook-www` and `builds/facebook-fbsource` branches from receiving new build artifacts. This in turn blocks DiffTrain from syncing React changes into Meta's internal monorepo. DiffTrain build for [bf45a68dd35ed08860b6a70fed641dfe6d7d290d](facebook/react@bf45a68) Reviewed By: zeyap Differential Revision: D101329586 fbshipit-source-id: d38877d5cc964c46257cb73678f80d0a7c729d90
…ce node (#56479) Summary: Pull Request resolved: #56479 ## Changelog: [General] [Fixed] - support multiple old pseudo elements for same name but different source node We will need to track multiple old pseudo elements for same name but different source node when doing a series of shared transitions: 1. go from component A to component B (A stays hidden with Activity but not unmounted) 2. go back to A (B unmounted) 3. hide A and show B again A will lose its old pseudo element node, because at #1, B's old pseudo element node overrides A's (since they have the same vt name), and at #2, B's old node gets cleaned up. At #3, since createViewTransitionInstance won't be called for A again (react reconciler assumes the instance is only created once until a component is unmounted), there's no valid old node for A anymore. Reviewed By: sammy-SC Differential Revision: D101237889 fbshipit-source-id: 4f670877e3786f0aa89409c1fd5b9784515bd2c2
Summary: Pull Request resolved: #56474 On Android, pressing the hardware back button while LogBox notification toasts or the full inspector overlay are visible has no effect on the JS side. The only way to dismiss notifications is the on-screen X button, and the only way to close the inspector is via Minimize/Dismiss. This adds `BackHandler` listeners to both JS containers: **Notification toasts**: A new `LogBoxNotificationBackHandler` component mounts alongside the toasts and registers a `hardwareBackPress` listener that calls `clearWarnings()` + `clearErrors()`, equivalent to pressing X on every visible toast. The component returns null and auto-cleans the listener on unmount. **Inspector overlay**: `LogBoxInspectorContainer` registers a `hardwareBackPress` listener in `componentDidMount` that calls `_handleMinimize()` (`setSelectedLog(-1)`), closing the overlay non-destructively — same as pressing the Minimize button. Changelog: [Android][Added] - Allow LogBox notification toasts and inspector overlay to be dismissed via Android back button Reviewed By: alanleedev Differential Revision: D101178179 fbshipit-source-id: c2100d2cc494c326d8a91caa906faabb3d23381c
Summary: Pull Request resolved: #56478 Changelog: [General] [Fixed] - Respect enum values for TurboModule c++ codegen Defining an enum like this: ```js export enum CustomPropertyEditor { BitMask = 0, Entity = 1, Slider = 2, AudioEvent = 3, CollisionLayer = 4, MaterialComponentDeprecatedProperty = 5, MeshMaterialList = 6, Submesh = 7, // CoreUiLayout (8) removed — rendered identically to ClassOrList MaterialMapJson = 9, AnimationTable = 10, SkeletonAsset = 11, NavMeshAreaType = 12, VFXAsset = 13, Table = 14, VariableTable = 15, AudioBus = 16, LodSettings = 17, WorldSearch = 18, EntityMaterialList = 19, NpcId = 20, LightingModelVersion = 21, PlatformSelector = 22, ComponentReference = 23, } ``` (notice number 8 ), will cause the generated enum to actually look like: ``` enum class NativeEditableObjectModuleCustomPropertyEditor { BitMask, Entity, Slider, AudioEvent, CollisionLayer, MaterialComponentDeprecatedProperty, MeshMaterialList, Submesh, MaterialMapJson, AnimationTable, ... }; ``` in other words, the values don't match up after the core ui value. This is quite dangerous and I'm surprised no one has ever noticed that This diff fixes things such that if an integer value is explicitly assigned, the value is preserved in the generated enum. Reviewed By: christophpurrer Differential Revision: D101229471 fbshipit-source-id: 366ea2d16ac74e112f1b68c5ad3d0877dedb918c
…gWarn (#56494) Summary: Pull Request resolved: #56494 Changelog: [Internal] ## Problem `RCTSyncImageManager` (used exclusively in test environments) calls `RCTLogError` when a network image fails to load within 20 seconds. On iOS, `RCTLogError` triggers a **native redbox** — a full-screen red overlay that: 1. **Covers the entire app UI**, making all elements invisible to E2E test assertions 2. **Cannot be dismissed on iOS** — `NativeExceptionsManager.dismissRedbox()` is a no-op (empty method in `RCTExceptionsManager.mm`) 3. **Cannot be suppressed by JavaScript-side mechanisms** — `LogBox.ignoreAllLogs()` and `suppress_warning` mobile config only affect JS-level LogBox, not native `RCTLogError` redboxes 4. **Instantly fails any E2E test** at the next `toBeVisible()` / `toHaveText()` assertion because the redbox overlay blocks all UI elements This causes **~2-5% infrastructure flakiness** across all iOS E2E tests that render components with network images (e.g., recommendation cards, ad previews, profile images), due to transient image load timeouts in the CI test sandbox. ### Error Flow ``` Image URL request in test sandbox → Network timeout (sandbox cant fetch from lookaside.facebook.com) → RCTSyncImageManager.mm dispatch_group_wait expires (20s) → RCTLogError(@"Image timed out in test environment for url: %@") → RCTLog.mm: level >= RCTLOG_REDBOX_LEVEL → Native RedBox overlay shown (full-screen, undismissable on iOS) → All toBeVisible() assertions fail → Test marked as FAILED ``` Differential Revision: D101052445 fbshipit-source-id: f615ac48ca210c5b070798f95ab2675ab9449e70
Summary: Pull Request resolved: #56472 Fix clang-diagnostic-unused-parameter warnings by commenting out the unused 'context' parameter in two fromRawValue functions. This maintains API compatibility while resolving the lint warnings. Changelog: [Internal] Reviewed By: NickGerleman Differential Revision: D101108449 fbshipit-source-id: 34da8573326c1ebc11dad01104f8857a21c0adc5
Summary: Pull Request resolved: #56495 UIManagerBinding::dispatchEvent checks for an existing timeStamp property before injecting one, but only checks the camelCase variant. Native events that use lowercase timestamp (e.g. pointer events) would have a duplicate timeStamp injected with the current time, which then takes precedence in the SyntheticEvent timestamp resolution chain (event.timeStamp || event.timestamp). This adds a check for both timeStamp and timestamp before auto-injecting, preserving the original native event timestamp when present in either casing. Root cause: #55878 only checked for timeStamp (camelCase). Changelog: [General][Fixed] - Fix event timestamp injection overriding native timestamps with lowercase property name Reviewed By: mdvacca Differential Revision: D101522871 fbshipit-source-id: 74d91a3958ac73927251189f07f954303d45688e
…#56497) Summary: Pull Request resolved: #56497 Reorder the fields to match the struct declaration order: text, selectionRange, contentSize, contentOffset, contentInset, eventCount, layoutMeasurement, zoomScale. Changelog: [Internal] Reviewed By: christophpurrer Differential Revision: D101560071 fbshipit-source-id: 462db623b62ed2cf01481c9406a8c750ff1268bc
Summary: Pull Request resolved: #56501 Add an early NPM token validation step to the create-release workflow. This runs `npm whoami` right after checkout to fail fast if the token is expired or invalid, avoiding wasted CI time on a release that would fail at the publish step. The step gracefully skips when no token is present (e.g. fork PRs). ## Changelog: [Internal] - Reviewed By: christophpurrer Differential Revision: D101377190 fbshipit-source-id: 53243a24649f86d274b2ea31793333fd815e69cb
Summary: Pull Request resolved: #56502 Adds an NPM token validation step to the `build_npm_package` job of the React Native nightly workflow. Mirrors the same check we recently added to `create-release.yml` and the Hermes `rn-build-hermes.yml` workflows so we fail fast (with a clear message) instead of failing partway through the publish step when the token is expired or missing. ## Changelog: [Internal] - Reviewed By: fabriziocucci Differential Revision: D101594276 fbshipit-source-id: bb0fbddf5eba921f4184117dc29c7cc9e911a00e
Summary: Pull Request resolved: #56503 Changelog: [Internal] Changes the signals pointing out C++ api snapshot not being updated to be blocking. Commits the new baseline snapshots Reviewed By: cipolleschi, cortinico Differential Revision: D101617655 fbshipit-source-id: 8836cb55292ab2e3fa0b696d289f9bd0daf46dec
Summary: Pull Request resolved: #56485 ## Changelog: [Internal] [Fixed] - Clear AnimatedPropsRegistry on surface stop When `useSharedAnimatedBackend` is enabled, the `AnimatedPropsRegistry` accumulates `SurfaceContext` entries (containing `shared_ptr<ShadowNodeFamily>` and `PropsSnapshot` data) for each surface that has animated views. These entries are never cleaned up when a surface is destroyed via `UIManager::stopSurface()`, because that method only calls the legacy `stopSurfaceForAnimationDelegate()` — the shared backend's registry is untouched. We also see increased `RetryableMountingLayerException` errors in production which stack trace shows there are mount items committing to surface that no longer exists. This change: 1. Adds `animationBackend_->clearRegistry(surfaceId)` to `UIManager::stopSurface()` 2. Changes `AnimatedPropsRegistry::clear()` to fully erase the `surfaceContexts_` map entry instead of just clearing its contents Reviewed By: christophpurrer Differential Revision: D101354994 fbshipit-source-id: c7668f728050a0d3f5c09ad5ca51e48450c1b87e
Summary: Pull Request resolved: #56511 ## Changelog: [Internal] [Fixed] - Fix react-native-cxx-stable-api-snapshot-validation test Reviewed By: jeffrey-beauchamp Differential Revision: D101646907 fbshipit-source-id: 6fda6032ee3a9b1c418ea19c7fffd5aabe614fb2
Summary: Pull Request resolved: #56488 Fixed clang-diagnostic-unused-parameter warnings in IMountingManager.h by commenting out parameter names while preserving types. This maintains API compatibility for virtual methods while eliminating lint warnings. Changelog: [Internal] Reviewed By: javache Differential Revision: D101110289 fbshipit-source-id: ee9bf593b648c6db8e0764613b29e47036fd7df8
Summary: Pull Request resolved: #56506 React Native's `PerformanceObserver` previously defaulted `durationThreshold` to 0 for `event` entries, while the W3C Event Timing spec (https://www.w3.org/TR/event-timing/#sec-modifications-perf-timeline) mandates a default of 104ms. The previous default flooded observers with short events (clicks, pointer up/down) that are not interesting for responsiveness measurement. This change brings React Native in line with the spec by making 104ms the default. The default is applied at the JSI bridge boundary in `NativePerformance.cpp` (the JS API boundary on the C++ side) when JS does not provide an explicit `durationThreshold`. The C++ public observer API (`PerformanceObserverObserveSingleOptions::durationThreshold`) and the global event buffer (`eventBuffer_.durationThreshold`) keep their `HighResDuration::zero()` default — applying 104ms to the global buffer would drop sub-104ms events at the source, breaking observers that explicitly request `durationThreshold: 0`. Changes in `react-native`: - `NativePerformance.cpp`: apply 104ms default at the JSI bridge boundary. - `PerformanceApiExample.js` (rn-tester): pass `durationThreshold: 0` to preserve previous behavior. - `EventTimingAPI-itest.js`: migrate 4 existing call sites to `{type: 'event', durationThreshold: 0}` and add a new test verifying the 104ms default. Sites using `{entryTypes: ['event']}` were converted to `{type: 'event', durationThreshold: 0}` since the spec (and existing JS validation in `PerformanceObserver.js`) disallows `durationThreshold` together with `entryTypes`. Changelog: [General][Fixed] - PerformanceObserver: `observe({type: 'event'})` now correctly defaults `durationThreshold` to 104ms per the W3C Event Timing spec instead of reporting all events. Reviewed By: hoxyq Differential Revision: D101629586 fbshipit-source-id: 897914e8582a3d16db9e9388606be5d0aebd19ab
Summary: Pull Request resolved: #56514 Changelog: [Internal] Reviewed By: rubennorte Differential Revision: D101652820 fbshipit-source-id: f7608fbf92a8fd2928434e74ad03bfc01b318d20
…r-modern (#56496) Summary: Pull Request resolved: #56496 Add a guard in the `Tracing.end` CDP handler to check `sessionState_.hasPendingTraceRecording` before calling `stopTracing()`. This prevents a null-pointer crash (SIGSEGV) in `HostTargetTraceRecording::stop()` when `Tracing.end` is sent after `Tracing.start` was rejected (e.g. due to multiple registered host targets in the global inspector singleton). The guard matches the existing pattern in `TracingAgent::~TracingAgent()` (line 29). When tracing was never started, it now returns an `InvalidRequest` error instead of crashing. Changelog: [Internal] Reviewed By: huntie Differential Revision: D101557975 fbshipit-source-id: 3ab754b9421b3bee3e3bde99ce012007d5a10368
Summary: Pull Request resolved: #56493 Fixed clang-diagnostic-unused-parameter warnings in EventQueueProcessorTest.cpp by removing unused parameter names from lambda functions. Changes: - Line 51: Removed parameter name 'runtime' from dummyEventPipeConclusion lambda - Line 52: Removed parameter name 'stateUpdate' from dummyStatePipe lambda This is a standard C++ practice for handling unused parameters - keeping the type for API compatibility while removing the name to silence the warning. Changelog: [Internal] Reviewed By: zeyap Differential Revision: D101110552 fbshipit-source-id: 3391080dcaa4c865177e164869b9732952cde906
Summary: Pull Request resolved: #56516 Fixed clang-diagnostic-unused-parameter warnings in TimerManager.cpp by commenting out the unused 'runtime' parameter names in two functions: - deleteTimer() at line 135 - deleteRecurringTimer() at line 152-153 Both functions accept a jsi::Runtime& parameter for API compatibility but don't use it internally. The fix maintains the function signatures while suppressing the warnings by commenting out the parameter names. Changelog: [Internal] Reviewed By: zeyap Differential Revision: D101108602 fbshipit-source-id: 95554385c6d36e724fdc1de4a3b20e1e1014a39c
Summary: Pull Request resolved: #56489 C++ enums cannot have float values - they must be int or long. This removes the invalid FloatEnum example (with values 0.0, 0.1, 0.2) from the react-native-codegen test fixtures and the corresponding enumFloat parameter reference. All affected test snapshots have been regenerated. Changelog: [Internal] Reviewed By: shwanton Differential Revision: D101433764 fbshipit-source-id: eff21d3fa9c48ab11dfb8ef861ac0b8122ff5602
Summary: Pull Request resolved: #56518 The fix adds null-coalescing fallbacks (`?: ""`) for UTF8String calls that return `const char * _Nullable` but are passed to `std::string` constructors or C++ functions expecting `const char * _Nonnull`. Changelog: [Internal] Reviewed By: christophpurrer Differential Revision: D101668743 fbshipit-source-id: 80920f25317b0c258387f4b2701b35afe20e3896
Summary: Add Changelog for 0.85.2 ## Changelog: [Internal] - Add Changelog for 0.85.2 Pull Request resolved: #56515 Test Plan: N/A Reviewed By: christophpurrer Differential Revision: D101668302 Pulled By: cipolleschi fbshipit-source-id: 1c3e4c6e7751fe35ab8c2af31181ad53d43dc8fe
Summary: X-link: facebook/yoga#1944 Pull Request resolved: #56784 Migrate YogaUnit.java to YogaUnit.kt by adding Unit to KOTLIN_ENUM_NAMES in enums.py and regenerating. Reviewed By: fabriziocucci Differential Revision: D104666347 fbshipit-source-id: 99f58b2d1cbea1592a3f4d1aa2608d42ba17e095
Summary: X-link: facebook/yoga#1949 Pull Request resolved: #56793 Migrate YogaWrap.java to YogaWrap.kt by adding Wrap to KOTLIN_ENUM_NAMES in enums.py and regenerating. All enums are now migrated to Kotlin — KOTLIN_ENUM_NAMES now contains all enum names. Reviewed By: fabriziocucci Differential Revision: D104666339 fbshipit-source-id: c30cac3d1f8cd5d8ac863c961ad7c90f4371cc58
Summary: Pull Request resolved: #56810 [changelog](https://github.com/facebook/flow/blob/main/Changelog.md) Changelog: [Internal] Reviewed By: panagosg7 Differential Revision: D105015188 fbshipit-source-id: e224f3112fa1c4b707fb1485c9474df5c5f6e53a
…ks (#56803) Summary: Two developers (or one developer on two paths, or CI vs. local) running pod install on the same React Native project at the same commit get different SPEC CHECKSUMS entries for React-Core-prebuilt and ReactNativeDependencies in Podfile.lock. That breaks pod install-deployment style verification and any workflow that expects Podfile.lock to be reproducible. CocoaPods derives each SPEC CHECKSUMS entry by hashing the in-memory podspec JSON. So anything embedded in source.http, prepare_command, user_target_xcconfig, etc. becomes part of the hash. Two podspec-resolution sites in this repo build their source.http from an absolute on-disk path. Because project_pods_root is an absolute path, the resulting file://<abs>/... URL differs across machines or working-tree paths, so the hashed JSON differs, so the checksum differs. ### How The Maven URL for each tarball is already computed inside both functions (stable_tarball_url(...) / nightly_tarball_url(...) / release_tarball_url(...)). Returning that URL — a stable string identical across machines — instead of the local file:// URL makes source.http path-free. CocoaPods downloads from Maven and caches the tarball itself, so functionality is preserved. The pre-existing local-tarball download is kept untouched (its only remaining consumer is the opt-in `RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS=1` dSYM-injection path in rncore.rb, which still needs file:// to feed CocoaPods a mutated tarball — gated by unless @download_dsyms so the leak is preserved only for that flag). **Out of scope: ** hermes-engine.podspec has the same shape of leak in user_target_xcconfig.HERMES_CLI_PATH. Fixing it requires a paired change to ensure hermesc lands at the new ${PODS_ROOT}-relative path; that's a separate PR. ## Changelog: [IOS] [FIXED] - Fix Pod install checksum drifting Pull Request resolved: #56803 Test Plan: Run `pod install` and verify that none of the following files contains absolute paths: - Pods/Local Podspecs/React-Core-prebuilt.podspec.json - Pods/Local Podspecs/ReactNativeDependencies.podspec.json Reviewed By: christophpurrer Differential Revision: D104889112 Pulled By: CalixTang fbshipit-source-id: 97505a8bf78f7df57bda2d87705da5a20c934d2b
Summary: Pull Request resolved: #56812 Update load-bearing `react/react-native-devtools-frontend` URLs following repo move. In particular, the `sync-and-build` script. URLs in code comments are preserved (rely on redirect / avoid churn). Changelog: [Internal] ___ overriding_review_checks_triggers_an_audit_and_retroactive_review Oncall Short Name: react_native_iroc Differential Revision: D105033074 fbshipit-source-id: 78545cb92d9623d9a115d1a940ba7efc78a5a6d8
#56814) Summary: Pull Request resolved: #56814 Any time we have a non-nullable accessibilityState prop, it appears to always set `expanded` false, which causes most Android screen readers to append or prepend "collapsed". This fixes the issue. ## Changelog [Android][Fixed] Screen reader behavior for accessibilityState expanded Reviewed By: javache Differential Revision: D105035390 fbshipit-source-id: 4b3b1b2a9b6e661cfde0f39d7de6a7cd7af91bb0
…dTouchTrack (#56819) Summary: Pull Request resolved: #56819 The native iOS touch system can occasionally dispatch touch events to JavaScript where `nativeEvent.changedTouches` is undefined due to inconsistencies between local and UIKit touch registries. This causes a TypeError crash in `ResponderTouchHistoryStore.recordTouchTrack` when it unconditionally calls `.forEach()` on `changedTouches`. The fix adds a defensive null check: if `changedTouches` is null/undefined, we log a DEV warning and bail out early from `recordTouchTrack`. Additionally, `nativeEvent.touches` accesses use optional chaining to prevent secondary crashes. Changelog: [iOS][Fixed] - Fix TypeError crash in ResponderTouchHistoryStore when changedTouches is undefined Reviewed By: fkgozali Differential Revision: D105023000 fbshipit-source-id: d3ade24e93f45614b094932e436f7190c8c0a985
Summary: Pull Request resolved: #56746 Add an RNTester PlatformTest case that calls Image.getSize against a small PNG, a large JPEG, and an EXIF-rotated JPEG, then verifies the dimensions reported by native image metadata. Extend the existing Image Maestro flow to open the new test and wait for the pass result, so the same flow can run against Android and iOS RNTester builds. Changelog: [Internal][Added] - Add RNTester device coverage for Image.getSize dimensions Reviewed By: christophpurrer Differential Revision: D104535939 fbshipit-source-id: 4f181ce7320af679dd4c409a5c813555914e580c
Summary: Pull Request resolved: #56808 Adds a `--watch` flag to `yarn build-types`. Helpful when debugging output TS types end-to-end. Changelog: [Internal] Reviewed By: robhogan Differential Revision: D104815967 fbshipit-source-id: 23ca53bffd5b0508272a5fad8bd4ca4314bb9d06
Summary: Pull Request resolved: #56824 Update the `simplifyTypes` transform (Flow → TS generation) to prune non-overlapping keys from `Omit<>` helpers in TypeScript `interface` unions. This greatly reduces API snapshot churn/inflation in the next two diffs, which convert a number of `type` declarations (trivial unions) to `interface` (`Omit<>` required for correct union). #### In detail `flow-api-translator` emits `Omit<ParentType, keys>` to faithfully translate Flow's object spread override semantics to TypeScript. ``` // Flow type Base = {x: string, y: number}; type Child = {...Base, x: boolean}; // Later properties in an object spread override earlier ones // TypeScript type Base = {x: string; y: number}; type Child = Omit<Base, "x" | "y"> & {x: boolean}; // Later properties in an object spread *merge*, rather than override. So we must use Omit<> for matched keys. ``` For `interface` type unions with overlapping keys, this can result in a number of unnecessary lines in the API snapshot, with little/no human readable value. This diff extends existing `Omit<>` handling by `simplifyTypes` to recursively resolve all property keys reachable from a type, and prune keys that don't exist on the parent type. ``` // TypeScript type Child = Omit<Base, "x"> & {x: boolean}; // Only "x" matched - strip `| "y"` type ChildTwo = Base & {z: string}; // No property collision - strip entire `Omit<>` ``` - See changes to `ReactNativeApi.d.ts`, [P2325468482](https://www.internalfb.com/phabricator/paste/view/P2325468482?view=diff) for examples. - **Decision point**: This diff opts to preserve correctness in TS — even though the snapshot isn't/isn't intended to be read directly/programatically, vs the conciseness tradeoff if we dropped all `Omit<>`s (human readable but ambiguous to the typechecker). Changelog: [Internal] - JS API snapshot changes are a simplification refactor only Reviewed By: robhogan Differential Revision: D105150070 fbshipit-source-id: 43b0ef517164332a5cfaee7a5de5747749ac5e7c
Summary: Pull Request resolved: #56822 Changelog: [Internal] Reviewed By: thegreatercurve Differential Revision: D104870951 fbshipit-source-id: 3b4bc9664ec1088eb944e68bf958e5e2b7b2d74c
…sabling block-scoping transform for SH (#56825) Summary: Pull Request resolved: #56825 Disable `babel/plugin-transform-block-scoping` when `customTransformOptions.unstable_preserveBlockScoping` is truthy. This allows us to experiment with native let/const block scoping support in Static Hermes. Changelog: [Internal] Reviewed By: vzaidman Differential Revision: D93013927 fbshipit-source-id: 6e2c1274426943fcf1ce5a8c09d677e1d0afb35f
…56801) Summary: Pull Request resolved: #56801 In preparation for enabling `enableSyncVoidMethods` (D104331837), which makes TurboModule void methods execute synchronously on the JS thread instead of being dispatched asynchronously. Currently, this module overrides `methodQueue` to return `dispatch_get_main_queue()` so its void methods execute on the main thread. When `enableSyncVoidMethods` is enabled, the `methodQueue` override is ignored for void methods — they execute directly on the JS thread. This causes crashes for any UI operations that must run on the main thread. **Fix:** Remove the `methodQueue` override. The `alertWithArgs` method already dispatches UI work onto the main thread via `RCTExecuteOnMainQueue`, so it is already safe. Changelog: [Internal] Reviewed By: javache Differential Revision: D104771644 fbshipit-source-id: 4f1eae55c64e56990efc20c4b32af1d722520037
Summary: ## Why Kotlin 2.2 changes the ABI for interface methods with default implementations. In Kotlin 2.1, these were emitted as 'public abstract' in the bytecode. In Kotlin 2.2, they are emitted as 'public' (non-abstract) with DefaultImpls. This causes React Native's binary compatibility validator to detect API changes. No impact on actual functionality: https://kotlinlang.org/docs/whatsnew22.html#changes-to-default-method-generation-for-interface-functions The new methods that appear in bytecode are expected, since they weren't overridden in the class. Updated ReactAndroid.api dump file by running: buck2 run //xplat/js/scripts/rn-api:generate-rn-api-metadata Affected interfaces: - ReactMarker.FabricMarkerListener - AppearanceModule.OverrideColorScheme - RCTEventEmitter - RCTModernEventEmitter - ReactNativeHost (new methods: getBundleFilePath, setBundleFilePath) - DialogRootViewGroup (new method: onChildStartedNativeGesture) ## Changelog [Internal] [Changed] - Pull Request resolved: #56833 Reviewed By: cortinico Differential Revision: D105216824 fbshipit-source-id: df5dede0b3d72b9fd1d6d89f377fa07f744a1c61
Summary: Pins the default `GITHUB_TOKEN` to `contents: read` on 2 workflows in `.github/workflows/` that don't call a GitHub API beyond the initial checkout. The following files were left implicit because they reference `GITHUB_TOKEN` / use a write-scope action / trigger on `pull_request_target`. Those scopes are best declared by maintainers: `cache-reaper.yml`, `check-for-reproducer.yml`, `retry-workflow.yml`, `validate-dotslash-artifacts.yml`. ## Why CVE-2025-30066 (March 2025 `tj-actions/changed-files` supply-chain compromise) exfiltrated `GITHUB_TOKEN` from workflow logs. Pinning per workflow caps runtime authority irrespective of the repo or org default, gives drift protection if the default ever widens, and is credited per-file by the OpenSSF Scorecard `Token-Permissions` check. YAML validated locally with `yaml.safe_load` on each touched file. ## Changelog [Internal] [Changed] - Pull Request resolved: #56834 Reviewed By: cipolleschi Differential Revision: D105294446 Pulled By: cortinico fbshipit-source-id: c90e885345f7b49d6c3ccfd73fdbd7ce8eebe4a1
Summary: Pull Request resolved: #56826 This class was fully stubbed out as part of the Legacy Architecture removal. All public methods had empty bodies or returned null/0, meaning any OSS library still referencing it was already silently broken at runtime. - `UIImplementation` — all methods empty stubs Also removes the dead `getUIImplementation()` method from `UIManagerModule`, and cleans up stale Javadoc references in `JSTouchDispatcher`, `ReactViewGroup`, and `ReactInterceptingViewGroup`. `UIBlock`, `NativeViewHierarchyManager`, `UIViewOperationQueue`, and the `addUIBlock`/`prependUIBlock` methods on `UIManagerModule` are retained and will be deprecated in a follow-up diff. Changelog: [Android][Removed] - Remove legacy architecture stub `UIImplementation`. This class was already non-functional (all methods were empty stubs). Reviewed By: christophpurrer Differential Revision: D104991922 fbshipit-source-id: 8a4bb015453f2bf441deec9ac914b08642faab44
Summary: X-link: facebook/yoga#1939 Pull Request resolved: #56780 Migrate YogaNodeJNIBase.java to YogaNodeJNIBase.kt, the last hand-written Java source file in the Yoga core library. This required converting all function overrides to Kotlin property overrides where the abstract YogaNode class declares them as val/var properties. Also changed nativePointer visibility in YogaConfigJNIBase from protected to internal to maintain same-module access that Java protected provided via package access. Changelog: [Internal] - Reviewed By: alanleedev Differential Revision: D104666335 fbshipit-source-id: c60285453e8a6ec834924be461da3c669d9a7be4
Currently, Hermes, ReactNativeDependencies, and ReactNativeCore tarballs are cached only inside the Pods/ directory. This means every clean `pod install` (or deleting the Pods folder) triggers a full re-download from Maven, even if the same version was already downloaded before. This adds a shared cache layer at ~/Library/Caches/ReactNative/. On first download, tarballs are saved to the shared cache. On subsequent pod installs, if the local Pods cache is empty but the shared cache has the tarball, it is copied locally instead of re-downloaded. This benefits: - Clean installs after deleting Pods/ - Multiple projects using the same React Native version - CI environments with a persistent home directory Added descriptive log messages for each scenario (local hit, shared cache hit, cache miss + download) to aid debugging.
cd6aaa7 to
2092992
Compare
Comment on lines
+138
to
+142
| needs: [generate_changelog, set_hermes_version] | ||
| uses: ./.github/workflows/create-draft-release.yml | ||
| secrets: inherit | ||
| with: | ||
| hermesVersion: ${{ needs.set_hermes_version.outputs.HERMES_VERSION }} |
Comment on lines
+29
to
+51
| runs-on: ubuntu-latest | ||
| if: github.repository == 'facebook/react-native' | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| fetch-depth: 0 | ||
| fetch-tags: true | ||
| - name: Setup node.js | ||
| uses: ./.github/actions/setup-node | ||
| - name: Install dependencies | ||
| uses: ./.github/actions/yarn-install | ||
| - name: Configure Git | ||
| shell: bash | ||
| run: | | ||
| git config --local user.email "bot@reactnative.dev" | ||
| git config --local user.name "React Native Bot" | ||
| - name: Validate DotSlash artifacts | ||
| uses: actions/github-script@v8 | ||
| with: | ||
| script: | | ||
| const {validateDotSlashArtifacts} = require('./scripts/releases/validate-dotslash-artifacts.js'); | ||
| await validateDotSlashArtifacts(); |
Fetches the .sha1 checksum from Maven for each downloaded tarball and validates file integrity at two points: 1. When reading from the shared cache: if the cached file's SHA1 doesn't match Maven's, it is treated as corrupted and re-downloaded, replacing the stale cache entry. 2. After a fresh download: validates the download succeeded correctly before saving to the shared cache. If verification fails, the file is not cached (but still used locally, as CocoaPods will re-extract it). If Maven doesn't serve a .sha1 for a given artifact (e.g. some nightly builds), validation is skipped gracefully.
Moves shared_cache_dir, fetch_maven_sha1, and validate_tarball into ReactNativePodsUtils in utils.rb to eliminate duplication across hermes-utils.rb, rndependencies.rb, and rncore.rb.
hermes-utils.rb cannot use require_relative to utils.rb because the folder structure differs between the monorepo and published npm package. Instead, hermes-utils.rb gets its own copy of shared_cache_dir, fetch_maven_sha1, and validate_hermes_tarball. Also adds explicit "Verifying checksum for cached/downloaded ..." log lines in all three download functions so the verification step is visible in pod install output.
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.
Adds a shared cache layer at
~/Library/Caches/ReactNative/for prebuilt iOS tarballs(Hermes, ReactNativeDependencies, ReactNativeCore).
Pods artifacts dir and the shared cache.
pod installruns, if the local Podscache is empty but the shared cache has the tarball for
that version, it is copied locally instead of
re-downloaded from Maven.
Pods hit, shared cache hit, and cache miss (download).
This avoids redundant downloads when:
Changelog:
[IOS] [CHANGED] - Cache prebuilt iOS binaries (Hermes,
ReactNativeDependencies, ReactNativeCore) in
~/Library/Caches/ReactNative to avoid redundant downloads
across pod installs
Test Plan:
Cold start ==> Downloading
Warn shared cache, Empty Pods dir ==> Copy
Warm Cache, Pods folder populated ==> Nothing happens