mirror of
https://github.com/react/react-native.git
synced 2026-09-28 13:23:09 +08:00
alanhughes/dev-menu-toggle
592
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b3839a3d03 |
Add deep-link Maestro flows for RNTester basics (#58480)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/58480 Add Maestro coverage for portable RNTester interaction scenarios using direct example deep links. The flows cover alerts, animations, appearance, filters, text input, and touchables without screenshot baselines. Changelog: [Internal] Reviewed By: Abbondanzo Differential Revision: D119484759 fbshipit-source-id: f17aa255cdbf860ac9864185b509ddddb34089e5 |
||
|
|
3e6b2bf8cc |
Retry artifact uploads in CI (#58620)
Summary: Artifact uploads can fail on transient network errors such as the `ETIMEDOUT` in https://github.com/react/react-native/actions/runs/35598907154/job/106330670539. This change: - adds a local composite action backed by `actions/upload-artifact` v7.0.1 - retries failed uploads twice, waiting 10 seconds before attempt 2 and 20 seconds before attempt 3 - propagates the third failure to the caller - preserves all v7 inputs and outputs - migrates all 35 artifact upload call sites to the wrapper ## Changelog: [INTERNAL] [FIXED] - Retry artifact uploads to reduce transient CI failures. Pull Request resolved: https://github.com/react/react-native/pull/58620 Test Plan: - `node_modules/.bin/prettier --check $(git diff --name-only HEAD^ -- '*.yml' '*.yaml')` — passed - `npx --yes action-validator/cli@0.6.0 .github/actions/upload-artifact/action.yml` — passed - `git diff HEAD^ --check` — passed - Verified no `actions/upload-artifact@v6` references remain under `.github` Reviewed By: andrewdacenko Differential Revision: D121002745 Pulled By: cortinico fbshipit-source-id: e63e30f3e86b0a2cb6c94aa549cdfe5e6dfbdc2b |
||
|
|
9da1baccc8 |
Configure Swift formatting in CI (#58616)
Summary: The format workflow currently runs on `macos-15`, whose default Xcode 16.4 toolchain does not meet the repository formatter's Swift 6.3 minimum. As a result, `format-swift.js` warns and skips Swift files. Run the format job on `macos-26` and explicitly select Xcode 26.6.0 so that `swift format` 6.3 is available and Swift formatting is actually exercised in CI. This does not include the unrelated C++ formatting change currently making the job red on `main`. ## Changelog: [INTERNAL] [FIXED] - Configure Swift formatting in the format workflow Pull Request resolved: https://github.com/react/react-native/pull/58616 Test Plan: - `yarn prettier --check .github/workflows/format.yml` — passes. - `swift format --version` — reports `6.3.0` locally. - [GitHub format run](https://github.com/react/react-native/actions/runs/35590873668/job/106304725401) — the macOS 26 runner accepted Xcode 26.6.0, and `format-swift.js` completed without the missing Swift 6.3 warning. The job remains red because enabling the formatter exposes existing formatting changes (along with the unrelated C++ formatting issue already present on `main`). Reviewed By: cipolleschi Differential Revision: D120988250 Pulled By: cortinico fbshipit-source-id: f21ae2b52041edf84bf142c770ffe0da2821654a |
||
|
|
15d3bcad5a |
Move Android template app E2E builds to Docker (#58564)
Summary: Move Android template app APK generation into a dedicated reusable workflow that runs in `reactnativecommunity/react-native-android:latest`. The emulator workflow now downloads the prebuilt debug or release APK and runs Maestro directly on the Ubuntu host. Only the debug lane reconstructs the generated project as a Metro workspace. E2E retries reuse the original APK artifacts instead of rebuilding the app. This keeps KVM-backed emulators on the host while removing Gradle and NDK provisioning from the emulator jobs. It also aligns the template app flow with the existing RNTester build/test artifact boundary. ## Changelog: [INTERNAL] [FIXED] - Build Android template E2E APKs in the Android container. Pull Request resolved: https://github.com/react/react-native/pull/58564 Test Plan: - `yarn prettier --check .github/workflows/build-android-templateapp.yml .github/workflows/e2e-android-templateapp.yml .github/workflows/test-all.yml` — passed - `git diff --check` — passed - Parsed all three changed workflow files with the repository's `yaml` package — passed - Container build and emulator E2E were not run locally because Docker is unavailable; the GitHub Actions PR run will exercise the complete workflow. Reviewed By: cipolleschi Differential Revision: D120393969 Pulled By: cortinico fbshipit-source-id: fde7eadd4f87145ccf501df4de214a5101df4746 |
||
|
|
a9307d8202 |
Split the iOS E2E template-app workflow and harden the Maestro runner (#58484)
Summary: This PR separates the template app's iOS build from its Maestro test run and updates the shared iOS runner: - Extract the existing template-app build steps into a `build` job. The project initialization, CocoaPods setup, and `xcodebuild` commands come from the previous combined `test` job; `Prepare artifacts` is renamed to `Build the app`. - Add a separate `test` job that depends on `build` and runs the Debug and Release apps. It repeats the checkout, Node, and Yarn setup from the old job and moves the existing Maestro execution and status reporting into this job. Both jobs keep `macos-26-large`. - Upload the built apps as artifacts and download them in the test job. Enable artifact replacement so the existing workflow retries can upload rebuilt apps under the same names. - Add `Prepare project for Metro` for Debug tests. Its package lookup, template-branch selection, and `init-project-e2e.js` invocation are copied from the existing `Prepare artifacts` step. The new job has a fresh filesystem, so it needs to recreate the JavaScript project for Metro; this step only repeats project initialization, leaving CocoaPods and the native build in the build job. - Update Maestro's `app-path` to point to the downloaded `RNTestProject.app`, replacing the path to the previous job's local Xcode build output. - Pass the selected simulator's UDID to app installation and video recording instead of using `booted`, so both target the same simulator as Maestro. - Make flow execution asynchronous and await the recorder's exit after sending SIGINT, so the video finishes writing and Node processes the child exit before the next flow starts. Send SIGKILL if the recorder has not exited within 30 seconds. (The missing wait predates this PR. Recordings were already uploaded as artifacts, but CI did not validate the videos, so recording problems could go unnoticed. [https://github.com/react/react-native/issues/57749](https://github.com/react/react-native/pull/57749) introduced a separate recorder per flow, reusing the same filenames, which allows the next recording to start before the previous one finishes.) - Skip `helpers/` when collecting flows, since these files are fragments included by other tests through `runFlow`. - Update unit tests to await flow execution and simulate recorder exit events. Add coverage for waiting on the recorder, skipping helpers, and reporting failure after all retries are exhausted. ## Changelog: [INTERNAL] [CHANGED] - Separate iOS template-app E2E builds from test execution and improve Maestro runner reliability. Pull Request resolved: https://github.com/react/react-native/pull/58484 Test Plan: - Author-reported E2E validation used `macos-26` instead of the checked-in `macos-26-large`: RNTester passed 38/38 flows in both Debug and Release, and the template app passed in both configurations. These runs were not repeated during this review. - Runner unit tests with the repository's Jest configuration: **8/8 passed** — `yarn jest .github/workflow-scripts/__tests__/maestro-ios-test.js`. - `node --check .github/workflow-scripts/maestro-ios.js` — passed. - Prettier check on the updated unit tests and workflow — passed. - `git diff --check` — passed. - E2E with the local fixes and artifact replacement during a GitHub Actions retry were not run during this review. Reviewed By: christophpurrer Differential Revision: D120135261 Pulled By: cipolleschi fbshipit-source-id: 8cd04d8a034d595d14d380831b418183ea697feb |
||
|
|
7a2963f2b5 |
Report formatting fixes on pull requests (#58464)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/58464 Add a GitHub Actions formatting check that runs the repository-wide formatter check and posts line-level suggested fixes through the GitHub API for files that need reformatting. Changelog: [Internal] Reviewed By: cipolleschi Differential Revision: D119487616 fbshipit-source-id: e8534888824b5e56fa949aef0ab1e64fe73c8d96 |
||
|
|
2364ae10b5 |
Fix failing iOS text width mode Maestro test (#58457)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/58457 Pin the RNTester iOS Debug, Release, and Maestro Cloud lanes to the same iPhone 17 Pro / iOS 26.2 profile. This keeps the existing 960x489 screenshot baseline valid across all three lanes while preserving automatic simulator selection for other action callers. Document that shared screenshot baselines require an explicit matching device profile. Changelog: [Internal] Reviewed By: christophpurrer Differential Revision: D119440006 fbshipit-source-id: e667400b55f08f539019ab7279db1ae61f6f98d8 |
||
|
|
9b8715910d |
Do not fail superseded Maestro Cloud runs (#58422)
Summary: Treat Maestro Cloud uploads stopped by a newer upload as successfully superseded instead of failing the GitHub Actions job. The action still fails the job for test failures, timeouts, and errors, including failures where no upload status is available. This allows the Maestro Cloud “Stop Previous Flows” setting to be re-enabled without creating failure tasks for intentionally superseded runs. Re-enabling that project setting remains a separate dashboard operation. ## Changelog: [INTERNAL] [FIXED] - Do not fail CI when a Maestro Cloud run is superseded Pull Request resolved: https://github.com/react/react-native/pull/58422 Test Plan: - `git diff --check` — passed - `./node_modules/.bin/prettier --check .github/workflows/maestro-cloud-rntester.yml` — passed - Exercised the result gate for STOPPED, ERROR, missing-status failure, and SUCCESS outcomes — passed Reviewed By: cipolleschi Differential Revision: D119329958 Pulled By: cortinico fbshipit-source-id: 94dd5efba87f2a9af7261daaee146f839ade380d |
||
|
|
f82830d21c |
Use a variable for the Maestro Cloud project ID (#58408)
Summary: Read the Maestro Cloud project ID from a GitHub Actions variable instead of a secret. Project IDs are identifiers rather than credentials, and secret masking currently redacts the project ID inside Maestro Cloud console URLs, making those links invalid. The API key remains a secret. The `MAESTRO_CLOUD_PROJECT_ID` repository variable has already been configured. ## Changelog: [INTERNAL] [FIXED] - Preserve Maestro Cloud console URLs in GitHub Actions logs Pull Request resolved: https://github.com/react/react-native/pull/58408 Test Plan: - `git diff --check` — passed - `./node_modules/.bin/prettier --check .github/workflows/maestro-cloud-rntester.yml` — passed - Verified `MAESTRO_CLOUD_PROJECT_ID` is available as a repository Actions variable Reviewed By: cipolleschi Differential Revision: D119322826 Pulled By: cortinico fbshipit-source-id: fc26750a93e7b421a891d496f2e2e66f8868410c |
||
|
|
b830082cf5 |
Use current PR state in analyze workflow (#58411)
Summary: The Analyze Pull Request workflow validates `context.payload.pull_request`, which is the event snapshot saved when a workflow run was created. Rerunning an old run after the PR description or base branch changes therefore validates stale state and can replace a passing check with an incorrect failure. Fetch the current pull request through `github.rest.pulls.get` before validating its body and base branch so new runs and reruns behave consistently. ## Changelog: [INTERNAL] Pull Request resolved: https://github.com/react/react-native/pull/58411 Test Plan: - `git diff --check` - Parsed `.github/workflows/analyze-pr.yml` with Ruby YAML. - Executed both embedded `github-script` blocks with a mocked valid live PR and stale invalid event payload; both used the live state and passed. - Executed both blocks with an invalid live PR and valid stale event payload; both used the live state and failed. - Full repository formatting could not run locally because Yarn package downloads repeatedly failed through the environment proxy with HTTP 503. Reviewed By: christophpurrer Differential Revision: D119215496 Pulled By: Abbondanzo fbshipit-source-id: 08dfb4272b2f89d221d02665c39df49383a747e0 |
||
|
|
4f95564c72 |
Add @expo/code-review-cli (#58021)
Summary: This adds an AI code review bot to React Native. It leaves a single comment on PRs with findings from three reviewers (correctness, security, consistency) and never blocks merging or auto-approves. How it works: - Config lives in `.expo-code-review/` — `config.jsonc`, shared prompts, and the three agent files. The model is `meta/muse-spark-1.2` (Muse Spark) using `META_API_KEY`. - Three workflows: auto-review on `pull_request`, on-demand `/review` comment, and `/dismiss` to hide a finding. They check out the base commit and run the published `expo/code-review-cli` via `npx`, so PR code is never executed. What changed: - Added `.expo-code-review/` with the config and prompts - Added `.github/workflows/expo-code-review.yml`, `expo-code-review-command.yml`, `expo-code-review-dismiss.yml` The bot is wired but dormant until the `META_API_KEY` secret is set (from https://developer.meta.com/ai/, stored as `EXPO_CODE_REVIEW_API_KEY` and forwarded as `META_API_KEY`). It now only runs when you add the `ai-review` label. ## Changelog: [INTERNAL] [ADDED] - Add expo/code-review-cli AI code review (Muse Spark) Pull Request resolved: https://github.com/react/react-native/pull/58021 Test Plan: Tested locally on `add-expo-code-review-muse-spark` (`Abbondanzo/react-native` fork): ```bash npx --yes expo/code-review-cli init --token-env META_API_KEY # set model to meta/muse-spark-1.2 in config.jsonc, workflows forward META_API_KEY from secrets.EXPO_CODE_REVIEW_API_KEY ECR_EXPECTED_TOKEN_ENV=META_API_KEY ecr verify-config # → OK — tokenEnv locked to META_API_KEY ecr doctor # → ✓ 3 agents (consistency, correctness, security), coordinator meta/muse-spark-1.2 ecr ref-check # → 1 ref(s) across 6 files — all resolve ecr review --json # → correctly waits for META_API_KEY ``` CI is `continue-on-error` and `pull-requests: write` only. After the secret is set, adding `ai-review` on a PR triggers the review. Reviewed By: zeyap Differential Revision: D117580751 Pulled By: Abbondanzo fbshipit-source-id: 9f6e5123b9d73d3f5cdf38c5f1fdabaec9a061c3 |
||
|
|
8a75a4defe |
Skip device-specific screenshot flows in Maestro Cloud (#58166)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/58166 The screenshot baselines used by two Android RNTester flows were captured on the local CI emulator and have fixed pixel dimensions that do not match the Maestro Cloud device profile. Tag those flows as local screenshot baselines and exclude that tag from the Android Maestro Cloud job. The existing local Android E2E job continues to run both flows and validate their screenshots. Changelog: [Internal] ___ Differential Revision: D117687713 fbshipit-source-id: de7cb4c8b395f204d672f8a209a29ccaa6ab0226 |
||
|
|
4eee1cd4f1 |
Add Maestro Cloud CI for RNTester (#58151)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/58151 Run the release RNTester Maestro flows in Maestro Cloud for iOS and Android on pushes to main and same-repository pull requests. Reuse the existing build artifacts and read both the API key and project ID from repository secrets. The existing local Maestro jobs remain unchanged because debug flows require a running bundler that is unavailable in Maestro Cloud. Changelog: [Internal] Reviewed By: cipolleschi Differential Revision: D117513755 fbshipit-source-id: 78ad2b627783c2a750796a1c95648b00c913f350 |
||
|
|
ea06a3191f |
Stabilize Android E2E tests for ARM64 APKs (#58140)
Summary: Stabilizes the Android RNTester E2E jobs after switching their APKs to ARM64 while continuing to run the emulator on an x86_64 host. - Updates the Android wide-gamut screenshot baseline using the stable ARM64 result from the API 35 emulator. The emulator does not support wide color, so the Display-P3 fixture is converted to solid sRGB red. - Marks the FlatList `maintainVisibleContentPosition` flows as Android release-only. These flows remain fully covered by the release APK, where they consistently pass, while avoiding debug-only timing failures caused by running the ARM64 debug runtime through native translation. - Adds generic tag filtering to the Android Maestro runner and unit coverage for it. Across seven post-migration `main` runs, the release APK passed every FlatList flow, while the debug APK consistently dropped or delayed Maestro interactions and skipped up to 172 frames during startup. ## Changelog: [INTERNAL] [FIXED] - Stabilize Android RNTester E2E tests when running ARM64 APKs on x86_64 emulators. Pull Request resolved: https://github.com/react/react-native/pull/58140 Test Plan: - `./node_modules/.bin/jest .github/workflow-scripts/__tests__/maestro-android-test.js --runInBand --config='{"testEnvironment":"node","transform":{},"roots":["<rootDir>/.github/workflow-scripts"]}'` — passed (3 tests) - `maestro 2.6.1 check-syntax` for all 24 tagged FlatList flows — passed - Prettier check for all changed text files — passed - `git diff --check` — passed - Verified the filtered RNTester suite contains 16 debug flows and excludes 24 release-only FlatList MVCP flows - Compared the new baseline against ARM64 CI screenshots: exact match for release; debug RMSE 0.0024 - Manually exercised the ARM64 release APK on an API 35 ARM64 emulator at 320×640: FlatList offsets progressed as expected (`500 → 544 → 2744 → 4944 → 7144`), and five rapid prepends reached `11500` Related failing run: https://github.com/react/react-native/actions/runs/32821468795 Reviewed By: Abbondanzo Differential Revision: D117361459 Pulled By: cortinico fbshipit-source-id: 4514f8c42f7599c875672efe3c56aae7c9f0395c |
||
|
|
5d91707cfb |
Fix Core dSYM Maven URLs in GitHub release notes (#58114)
Summary: The GitHub release body generated by `createDraftRelease.js` labeled the last section **ReactNative Core dSYMs**, but the Maven URLs omitted the `dSYM-` classifier. That made the links download the prebuilt `React.xcframework` tarball (`reactnative-core-debug.tar.gz` / `reactnative-core-release.tar.gz`) instead of the actual dSYMs (`reactnative-core-dSYM-debug.tar.gz` / `reactnative-core-dSYM-release.tar.gz`). Hermes and ReactNativeDependencies links already include `dSYM-`; Core did not. This matches the classifier used when publishing Core dSYMs and the URL `rncore.rb` builds when `RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS=1`. Companion docs fix: https://github.com/reactwg/react-native-releases/pull/1394 ## Changelog: [INTERNAL][FIXED] - Point GitHub release Core dSYM links at the dSYM Maven artifacts instead of the framework tarballs Pull Request resolved: https://github.com/react/react-native/pull/58114 Test Plan: - Updated the expected strings in `.github/workflow-scripts/__tests__/createDraftRelease-test.js` to match the corrected URLs. - Did not run Jest locally: a full `yarn install` in this monorepo rewrites `hermes-compiler` / `yarn.lock` via the preinstall hook. - Confirmed the new URLs follow the same `dSYM-` classifier already used for ReactNativeDependencies in this template, and for Core dSYMs in `packages/react-native/scripts/cocoapods/rncore.rb` (`stable_tarball_url(..., dsyms = true)`). Reviewed By: GijsWeterings Differential Revision: D117330772 Pulled By: cipolleschi fbshipit-source-id: 761f4b821a05f078ea9d1a9cb1882edca822a834 |
||
|
|
4f9f24e957 |
Use legacy JNI packaging for ARM64 Android E2E APKs (#58103)
Summary: Follow-up to https://github.com/react/react-native/issues/58092. Android API 35 x86_64 emulator images expose both `x86_64` and `arm64-v8a` through `libndk_translation.so`. SoLoader 0.12.1 only searches the first ABI when loading uncompressed native libraries directly from the APK, causing ARM64-only RNTester and template apps to crash while loading `libreactnative.so`. Enable legacy JNI packaging through a CI-only Gradle init script so Android extracts the ARM64 libraries and the existing SoLoader `ApplicationSoSource` can load them. This applies only to dry-run RNTester builds and Android template E2E builds. Nightly and release packaging is unchanged. Failure evidence: https://github.com/react/react-native/actions/runs/32741094253 ## Changelog: [INTERNAL] [FIXED] - Extract native libraries for ARM64 Android E2E APKs running through NDK translation. Pull Request resolved: https://github.com/react/react-native/pull/58103 Test Plan: - `./node_modules/.bin/prettier --check .github/actions/build-android/action.yml .github/workflows/e2e-android-templateapp.yml` — passed. - Parsed both modified YAML files with the `yaml` Node package — passed. - Parsed the embedded workflow shell scripts with `bash -n` — passed. - Compiled `.github/workflow-scripts/legacy-jni-packaging.gradle` with the Groovy compiler bundled with Gradle 9.4.1 — passed. - Full Android E2E validation is delegated to this draft PR because the local Gradle daemon could not establish its localhost connection. Reviewed By: christophpurrer Differential Revision: D117222109 Pulled By: cortinico fbshipit-source-id: 65e09a38eed84474a2f50f7f5847e1676da4411b |
||
|
|
25ebffd1f7 |
Run Android E2E with ARM64 APKs (#58092)
Summary: Build only the `arm64-v8a` Android ABI for dry-run CI artifacts and run the ARM64 RNTester and template-app APKs on an API 35 `google_apis` x86_64 emulator using the system images built-in NDK translation support. This also makes the Maestro emulator API level and target configurable, logs the device ABI/native-bridge configuration, and updates local RNTester artifact selection to use the ARM64 split. Release and nightly publication builds continue to build all supported Android ABIs. ## Changelog: [INTERNAL] [CHANGED] - Run Android E2E tests with ARM64 APKs through NDK translation. Pull Request resolved: https://github.com/react/react-native/pull/58092 Test Plan: - `node --check .github/workflow-scripts/maestro-android.js` — passed. - `node --check scripts/release-testing/test-release-local.js` — passed. - Parsed all modified YAML files with the `yaml` Node package — passed. - `./node_modules/.bin/prettier --check <modified files>` — passed. - `git diff --check HEAD~3..HEAD` — passed. - `actionlint` reported only existing repository metadata warnings for the custom `4-core-ubuntu` label and the missing description in the local `yarn-install` action. - `yarn test .github/workflow-scripts/__tests__/maestro-android-test.js --runInBand` could not start because the local dependency tree is missing `flow-parser`; restoring dependencies was blocked by HTTP 503 responses from the npm registry. - The draft CI run should validate ARM64 APK installation, Hermes startup, and the complete Maestro suites through `libndk_translation.so`. Reviewed By: Abbondanzo Differential Revision: D117195078 Pulled By: cortinico fbshipit-source-id: a78f2127f04e80c3b5ca4c95d2024dffb92ff122 |
||
|
|
4c022bbf7d |
Retry only failed Android E2E flows (#57998)
Summary: Android Maestro E2E jobs currently stop after the first flow that exhausts its in-process retries. The workflow-level retry then starts the whole suite again, including flows that already passed. This changes the retry model so that: - each CI attempt runs every selected flow once and continues after individual failures; - per-flow `passed`, `failed`, and `pending` state is saved atomically after every flow; - cumulative results and attempt counts are shown in the GitHub job summary and uploaded as an artifact; - retry workflows download that state and skip flows that already passed, running only failed or unfinished flows; - a flavor whose downloaded state is already fully passed skips emulator startup and APK installation entirely; - a missing state artifact falls back to running the full suite, so infrastructure failures remain retryable. The Android E2E timeout is increased from 60 to 90 minutes to give the initial all-flows attempt enough time to finish. The existing three workflow attempts now provide up to three executions per failing flow instead of multiplying workflow retries by in-process retries. ### CI follow-ups - RNTester Debug completed all 40 flows with 38 passes and 2 failures. Retry 1 downloaded its state, skipped exactly those 38 passing flows, and executed only the two failures, validating the selective retry behavior. - RNTester Release became unhealthy after an early flow failure and timed out while later flows were still pending. The state file was being written incrementally, but its artifact upload was inside the timed composite action and was killed by the same timeout. Moved state upload into the outer reusable workflow so `if: always()` preserves passed, failed, and pending results after an E2E timeout. - The next Release retry downloaded the preserved state, skipped its 7 prior passes, reran the remaining flows, and recovered to 40/40. A later matrix retry could still start that completed flavor and fail during an unnecessary APK installation, so retry jobs now skip the entire E2E action when downloaded state is fully passed. - Both `test_js` variants failed because the repository Jest preset throws whenever `console.error` is called, and the new failure-path unit test intentionally exercised a production error log. The test now mocks that expected log while continuing to assert the aggregate flow failure. - RNTester Debug consistently failed `image-wide-gamut.yml` with exactly 83.974% screenshot similarity and `legacy-native-module.yml` before the APIs search became visible, while Release passed both immediately. Reproducing Debug with an offline Android emulator showed the actual cause: importing `ImageExample.js` eagerly starts a Facebook image prefetch, and its promise could reject before the Image Loading Events example attached its rejection callback. That produced an `Uncaught (in promise): UnknownHostException` LogBox notification, which covered the screenshot and intercepted the APIs tab. The prefetch now attaches a rejection handler immediately while preserving the existing example-level success/failure reporting. No LogBox dismissal or E2E-specific workaround remains. - The remaining `image-wide-gamut.yml` failure was separate from LogBox: the flow explicitly accepted `P3: error` but then compared against a golden screenshot containing the successfully loaded Display-P3 fixture. The same ICC-profiled WebKit sample is now embedded as a compact data URI, removing the external network dependency, and the flow requires `P3: loaded` before screenshot comparison. ## Changelog: [INTERNAL] [CHANGED] - Retry only failed or unfinished Android Maestro E2E flows. Pull Request resolved: https://github.com/react/react-native/pull/57998 Test Plan: - `git diff --check` (passed) - `node --check .github/workflow-scripts/maestro-android.js` (passed) - `yarn jest .github/workflow-scripts/__tests__/maestro-android-test.js --runInBand --config '{"testEnvironment":"node","transform":{}}'` (passed) - `ruby -ryaml -e "ARGV.each { |file| YAML.parse_file(file) }" .github/actions/maestro-android/action.yml .github/workflows/e2e-android-rntester.yml .github/workflows/e2e-android-templateapp.yml .github/workflows/test-all.yml` (passed) - `yarn prettier --check .github/workflow-scripts/maestro-android.js .github/workflow-scripts/__tests__/maestro-android-test.js .github/actions/maestro-android/action.yml .github/workflows/e2e-android-rntester.yml .github/workflows/e2e-android-templateapp.yml .github/workflows/test-all.yml` (passed) - Verified the retry-state `jq` predicate returns false only when every recorded flow has passed. - `./node_modules/.bin/prettier --check packages/rn-tester/js/examples/Image/ImageExample.js` (passed) - Reproduced on a local Android Debug emulator with external DNS unavailable. Before the fix, `logcat` reported `Uncaught (in promise): UnknownHostException` and LogBox covered the bottom navigation. After the fix, no unhandled rejection or LogBox appeared, the APIs tab displayed `explorer_search`, and the wide-gamut example was unobstructed. - Verified on a local Android Debug emulator with external DNS unavailable that the embedded Display-P3 fixture reaches `P3: loaded` and renders without a network request. - The next Debug run passed the stricter `P3: loaded` gate but still reproduced the exact 83.974% screenshot mismatch, followed by the legacy APIs-search failure. This confirms the embedded Display-P3 fixture is loading and that a second Debug-only UI state remains. The previous action skipped its Maestro-log upload because the emulator wrapper masked the inner script failure, and it pulled `screen.mp4` before stopping the recorder, leaving an unplayable artifact. The runner now captures a PNG, UI hierarchy, logcat, and Metro output when each flow fails, stops `screenrecord` before pulling the MP4, and always uploads the diagnostic bundle. The next run will expose the actual obstructing UI so it can be fixed at its source. - The first diagnostic run exposed a flaw in the new evidence collection itself: Debug remained inside the E2E action far beyond its normal duration because the `uiautomator`/ADB capture commands were unbounded. Every diagnostic subprocess now has a 15-second timeout, so a problem collecting evidence is logged but can never stall later flows or prevent state persistence. - The captured screenshots and hierarchy identified the root cause shared by all remaining Debug failures (including one additional FlatList flow): `StaticViewConfigValidator` reported that `AndroidTextInput.validAttributes.fontVariationSettings` had the wrong value. The object-syntax change in https://github.com/react/react-native/issues/57929 added a JS processor to the static TextInput config, but runtime native view-config reflection still derived plain `true` from the native `String` prop. Debug validation therefore emitted a LogBox; its notifications covered the wide-gamut screenshot and FlatList controls, and its expanded console blocked the legacy APIs tab. Native view-config construction now recognizes `fontVariationSettings` and installs the same processor as the static config. This both makes validation agree and preserves object-to-string normalization when reflected native configs are active. A regression test verifies the reflected attribute matches the static processor and serializes object settings deterministically. - Targeted regression test: `yarn test packages/react-native/Libraries/ReactNative/__tests__/getNativeComponentAttributes-test.js --runInBand` (passed). - Both `test_js` variants then failed at ESLint before running tests because the new regression test lacked the required Flow file annotation and its CommonJS imports were not in repository order. Added `flow strict-local` and reordered the requires; the targeted Jest test and Prettier check remain green. - Final Android validation on `bd55f0aa4226`: the initial RNTester emulators lost ADB after three passing flows, so the outer state artifacts preserved those passes and marked the remaining work for retry. Retry 1 started fresh emulators, skipped the three prior passes, ran the remaining 37 flows, and finished with 40/40 passed in both Debug and Release; retry 2 was skipped. `image-wide-gamut.yml`, `legacy-native-module.yml`, and `flatlist-inverted-recycle-maintainvisible.yml` each passed on their first execution after the view-config fix. All Android checks are green, including Android builds, HelloWorld, TemplateApp E2E, and RNTester E2E. Reviewed By: Abbondanzo Differential Revision: D116463690 Pulled By: cipolleschi fbshipit-source-id: 20f6d04ac8e21cdbb1fd04618cd879df6d413276 |
||
|
|
2dd6d4b482 |
Use macOS 26 runners for iOS E2E tests (#57993)
Summary: Moves the RNTester and template app iOS E2E jobs from `macos-15-large` to `macos-26-large`. The new runner image ships with Xcode 26, which is now required by `idb-companion`, and the jobs use the image default Xcode so its hosted simulator platform is available. The Maestro runner discovers an available iPhone Pro simulator and boots it by UDID instead of depending on a device name tied to an older runner image. ### CI follow-ups - `test_e2e_ios_templateapp / test (Debug)` failed before the E2E tests because the explicitly selected Xcode 26.0.1 installation did not include the iOS Simulator platform. Removed the explicit Xcode selection from both E2E workflows so `macos-26-large` uses its default Xcode 26.6 installation and hosted simulator setup. - The RNTester E2E attempts then installed `idb-companion` successfully but failed to boot the hardcoded `iPhone 16 Pro`, which is not present on the macOS 26 image. Updated the Maestro iOS runner to discover an available iPhone Pro from the newest installed runtime and boot it by UDID, with a unit test covering selection across runtimes. ## Changelog: [INTERNAL] [FIXED] - Run iOS E2E tests on macOS 26 runners with Xcode 26. Pull Request resolved: https://github.com/react/react-native/pull/57993 Test Plan: - `git diff --check` - `yarn prettier --check .github/workflow-scripts/maestro-ios.js .github/workflow-scripts/__tests__/maestro-ios-test.js .github/workflows/e2e-ios-rntester.yml .github/workflows/e2e-ios-templateapp.yml` - `ruby -ryaml -e "ARGV.each { |path| YAML.parse_file(path) }" .github/workflows/e2e-ios-rntester.yml .github/workflows/e2e-ios-templateapp.yml` - `node --check .github/workflow-scripts/maestro-ios.js` - `yarn jest .github/workflow-scripts/__tests__/maestro-ios-test.js --runInBand --config '{"testEnvironment":"node","transform":{}}'` Reviewed By: alanleedev, mdvacca Differential Revision: D116460922 Pulled By: cipolleschi fbshipit-source-id: e769f017b874c9da76d63f19727c358719dbdbc6 |
||
|
|
bc35168d1b |
Back out "Add Maestro Cloud CI for RNTester" (#57948)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57948 Original commit changeset: 20a5feb21ec1 Original Phabricator Diff: D115732295 ## Changelog: [Internal] - Reviewed By: cortinico Differential Revision: D115880038 fbshipit-source-id: c3ccc0f46be029ec13866465df02d73d3b36413e |
||
|
|
789e54c827 |
Back out "Fix Maestro Cloud project ID reference" (#57947)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57947 Original commit changeset: f7475fa8fcd3 Original Phabricator Diff: D115871650 ## Changelog: [Internal] - Reviewed By: cortinico Differential Revision: D115880037 fbshipit-source-id: 0d4e121e37d087e94fa0e47642cd4fd8c3e07309 |
||
|
|
9c770f5718 |
Fix Maestro Cloud project ID reference (#57943)
Summary: - read the Maestro Cloud project ID from the repository secret in both iOS and Android jobs - match the existing repository configuration and unblock input validation The failing main run resolved vars.MAESTRO_CLOUD_PROJECT_ID to an empty string because MAESTRO_CLOUD_PROJECT_ID is configured as a GitHub Actions secret. Changelog: [Internal] [Changed] - Pull Request resolved: https://github.com/react/react-native/pull/57943 Test Plan: - node_modules/.bin/prettier --check .github/workflows/test-all.yml - git diff --check Reviewed By: huntie Differential Revision: D115871650 Pulled By: cortinico fbshipit-source-id: f7475fa8fcd30e334b9bf3d361f6f718bd0ca7e4 |
||
|
|
189bb445f6 |
Add Maestro Cloud CI for RNTester (#57919)
Summary: This integrates our CI to work with Maestro Cloud. The change is additive as the previous existing tests are untouched (also because the Debug Maestro tests require a running bundler which we can't have on Maestro Cloud). ## Changelog: [INTERNAL] - Pull Request resolved: https://github.com/react/react-native/pull/57919 Test Plan: CI Reviewed By: christophpurrer Differential Revision: D115732295 Pulled By: cortinico fbshipit-source-id: 20a5feb21ec130ba227655f415214f91548f2423 |
||
|
|
93f1e6af74 |
Drop outdated links to wiki (#57898)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57898 Changelog: [Internal] ___ Differential Revision: D115564599 fbshipit-source-id: 4714995277556fc60550780e7a911e60eeef2f0d |
||
|
|
1208178d3c |
CI: add SwiftPM iOS e2e workflows (RNTester, HelloWorld, new app) (#57659)
Summary: Adds CI coverage for the SwiftPM (SPM) iOS path, which currently has none. Three standalone workflows scaffold + convert an app to SPM using the prebuilt XCFrameworks and compile it for the iOS simulator: - `test-ios-spm-rntester.yml` — `packages/rn-tester` - `test-ios-spm-helloworld.yml` — `private/helloworld` - `test-ios-spm-newapp.yml` — a fresh copy of `private/helloworld`, wired to a Verdaccio-published build of this monorepo None of them use `react-native-community/cli`. The shared logic lives in two committed, locally-runnable scripts (`scripts/e2e/spm-prime-artifacts.js`, `scripts/e2e/spm-ios-e2e.js`); the workflows are thin wrappers. They run manually (`workflow_dispatch`) and nightly (`schedule`). This also adds an optional `slices` input to `prebuild-ios-dependencies.yml` and `prebuild-ios-core.yml`. It defaults to the full platform set, so existing callers (`test-all.yml`, releases) are unchanged; the e2e workflows request only `ios-simulator`, since that is all they compile against. ## Changelog: [INTERNAL] [ADDED] - CI workflows validating the SwiftPM iOS build (RNTester, HelloWorld, new app) Pull Request resolved: https://github.com/react/react-native/pull/57659 Test Plan: - Trialed the HelloWorld workflow on this branch (temporary push trigger, since removed): full run green for both Debug and Release, incl. the real `spm add` + `xcodebuild`. The `slices` input correctly collapsed the prebuild matrices to the single `ios-simulator` slice per flavor. - `node --check`, `prettier --check`, and `eslint` clean on both scripts; all workflow YAML validated. Reviewed By: huntie Differential Revision: D114044420 Pulled By: cipolleschi fbshipit-source-id: cb8723ae6d78bb765f3dc930d8010d4eb82ea4c0 |
||
|
|
67a813a948 |
Make Maestro iOS retries flow-specific (#57749)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57749 Run iOS Maestro flows in isolated processes and retry only the failing flow so transient driver failures do not restart the full suite. Add focused coverage for flow discovery and retry isolation. Changelog: [Internal] Reviewed By: cipolleschi Differential Revision: D113984013 fbshipit-source-id: d38013d048c39df0bc58a434c7327a2a1ad9f5e5 |
||
|
|
a44d68ec6d |
Split Android build from release publishing (#57714)
Summary: This should reduce the publishing time needed for `publish_react_native` by parallelizing Android & iOS build ## Changelog: [INTERNAL] - Pull Request resolved: https://github.com/react/react-native/pull/57714 Test Plan: N/A Reviewed By: cipolleschi Differential Revision: D113889729 Pulled By: cortinico fbshipit-source-id: aaa66a3cb9ce5c22bf15780503cf9a063c4b2725 |
||
|
|
3958c7fa97 |
Fix npm package build for docs-only changes (#57719)
Summary: The build_npm_package job uses always() so it can run when one platform-specific prerequisite is skipped. However, that also caused it to run when every artifact-producing prerequisite was skipped, as happens for Markdown-only pull requests. It then failed because there were no artifacts to download. Require at least one Android or Apple artifact-producing prerequisite to have succeeded before running the package build. Failing run: https://github.com/react/react-native/actions/runs/30290299313/job/90058215494?pr=57703 ## Changelog: [INTERNAL] [FIXED] - Skip the npm package build when all artifact-producing prerequisites are skipped Pull Request resolved: https://github.com/react/react-native/pull/57719 Test Plan: - ./node_modules/.bin/prettier --check .github/workflows/test-all.yml - Parsed .github/workflows/test-all.yml with Ruby YAML - git diff --check Reviewed By: cortinico Differential Revision: D113900588 Pulled By: cipolleschi fbshipit-source-id: f6979ca48b44cf807bf4db12e3c0106d720a9cb1 |
||
|
|
43b44ed7c3 |
fix(iOS): stage Hermes headers in prebuild compose job so ReactNativeHeaders resolves <hermes/...> (#57661)
Summary: The iOS prebuild workflow (`.github/workflows/prebuild-ios-core.yml`) splits into two jobs on separate runners: - **`build-rn-slice`** stages the hermes-ios headers during setup (`.build/artifacts/hermes/destroot/include/hermes`), but uploads only `.build/headers` + the SPM Products — **not** the hermes artifact. - **`compose-xcframework`** (fresh runner) runs the compose (`-c` → `buildXCFrameworks`), which computed the hermes include path from `.build/artifacts/hermes/destroot/include`. That directory never exists on the compose runner, so `hermesHeaders` resolved to `null` and the hermes-header fold in `headers-compose.js` was **silently skipped**. Net effect: the published `ReactNativeHeaders.xcframework` shipped without the `hermes/` namespace, so consumers (e.g. Expo prebuilt) couldn't resolve `<hermes/...>`. Because the value was `null` rather than a bad path, not even the existing warning fired — every nightly regressed silently. ## Fix Build-time staging, matching the artifact's self-contained design (the orphaned consumer-side sidecar + health check in `download-spm-artifacts.js` confirm the bake was intended to happen at compose time): - **Workflow:** `compose-xcframework` now re-stages the hermes-ios headers before composing — a `Set Hermes version` step (`$GITHUB_ENV` doesn't cross jobs) and a `Stage Hermes headers` step that extracts the tarball into `.build/artifacts/hermes`. Both are guarded by the same `cache-hit` condition as the sibling steps. - **Fail-closed guard:** the inline hermes resolution is extracted into an exported `resolveHermesHeaders(buildFolder, required)` with a `findFirst` fallback (mirroring the consumer-side stager). When a version-stamped CI cut can't find the headers it now **throws** instead of silently shipping without `hermes/`. Gated behind a new `--require-hermes` flag, which the workflow passes only when `version-type` is set — so local `-c` keeps the previous no-fold behavior. ## Changelog: [IOS] [FIXED] - Prebuilt `ReactNativeHeaders.xcframework` now ships the Hermes public headers so consumers resolve `<hermes/...>` out of the box Pull Request resolved: https://github.com/react/react-native/pull/57661 Test Plan: - New unit tests for `resolveHermesHeaders` (`__tests__/xcframework-test.js`): resolves at the standard path, resolves via the `findFirst` fallback, returns `null` when absent + not required, throws when absent + required. - `yarn jest packages/react-native/scripts/ios-prebuild/__tests__/xcframework-test.js --no-cache -i` → 4/4 pass (red before the resolver was exported). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed By: javache Differential Revision: D113554720 Pulled By: cipolleschi fbshipit-source-id: 30d21240ae97978e58a95ffdfad4088ed85536d4 |
||
|
|
60fac2e14d |
Fix post-release workflow failures (#57627)
Summary: Fixes the three post-release failures from the [0.87.0-rc.2 publish run](https://github.com/react/react-native/actions/runs/29775529785/): - Keep Flow annotations in `verifyArtifactsAreOnMaven.js` as comments so `actions/github-script` can load the file with plain Node. - Pin the Podfile lock workflow to `macos-15`, which provides the configured Xcode 16.4 version. - Use the canonical `react/react-native` owner for release asset API operations so upload POST requests are not redirected from the former owner. ## Changelog: [INTERNAL] [FIXED] - Fix post-release Maven verification, Podfile lock, and release asset jobs Pull Request resolved: https://github.com/react/react-native/pull/57627 Test Plan: ```sh node --check .github/workflow-scripts/verifyArtifactsAreOnMaven.js node --check scripts/releases/upload-release-assets-for-dotslash.js yarn jest .github/workflow-scripts/__tests__/verifyArtifactsAreOnMaven-test.js scripts/releases/__tests__/upload-release-assets-for-dotslash-test.js --runInBand ``` 13 tests and 15 snapshots pass. Reviewed By: zeyap Differential Revision: D113032768 Pulled By: cipolleschi fbshipit-source-id: df5f493603e6c25157fd7660b54aa409dcb742e7 |
||
|
|
95df50034b |
fix(iOS): stamp the React Native version in the prebuild compose job (#57603)
Summary: `prebuild-ios-core.yml` builds the prebuilt iOS core in two jobs: **`build-rn-slice`** compiles the React binary per platform slice, and **`compose-xcframework`** runs afterwards in its **own fresh checkout**, downloads the slice artifacts, and composes the shipped `React.xcframework` + `ReactNativeHeaders.xcframework` — re-deriving the shipped *headers* from that checkout. The "Set React Native version" step runs only in `build-rn-slice`. So the compiled **binary is stamped**, but the composed **headers are not**: the artifact ships `ReactNativeVersion.h` with the `1000.0.0` dev sentinel, internally inconsistent with its own binary (and with the npm package, which is stamped in its own publish job). This was latent for as long as the compose job has existed — it only started breaking consumers now because the header-facades / VFS-overlay-removal work changed *which file libraries actually read*. Previously header resolution (the VFS overlay, and the `Pods/Headers/Public` symlinks of the source pods) redirected reads to the **stamped npm copy**, so the sentinel bytes in the tarball were never consumed. With real materialized headers, the prebuilt copy now wins the search path, and any library gating on `REACT_NATIVE_VERSION_MAJOR/MINOR` compiles the wrong branch. That breaks `[ios] react-native-unistyles` in nightly-tests: its `#if REACT_NATIVE_VERSION_MINOR >= 81` sees `MINOR 0` and picks a removed pre-0.81 path (`shadowNodeFromValue`). **Fix — built-headers overlay (no re-stamp/revert).** The `build-rn-slice` job already stamps its checkout before building and uploads `.build/headers`, and the compose job already downloads it — it was just unused. `stageEntries` now takes an overlay dir and, **for `ReactNativeVersion.h` only**, prefers the built copy (stamped in the slice job) over the source sentinel. Header **layout** is still spec-derived from source (podspec inventory, collision detection, classification), and every **other** header still copies from source — so a stale build tree can never ship wrong header content, only the one build-generated version header is overlaid. No stamping of the compose checkout, no `git revert`, no cache-key desync. The compose cache key is bumped so pre-fix (unstamped) composed artifacts cached under the old key are not served. **Guard.** `headers-verify.js` gains `--require-stamped-version` (passed when a `version-type` is set) that hard-fails the compose verification if any composed `ReactNativeVersion.h` still contains the sentinel — turning any future regression into a red prebuild instead of silently broken community libraries. ## Changelog: [IOS] [FIXED] - Ship a version-stamped ReactNativeVersion.h in the prebuilt iOS core artifacts instead of the 1000.0.0 dev sentinel Pull Request resolved: https://github.com/react/react-native/pull/57603 Test Plan: - Local compose with a stamped `ReactNativeVersion.h` seeded into `.build/headers` and the source tree left at the `1000` sentinel: all composed `ReactNativeVersion.h` copies come out stamped (overlay won), while a deliberately **stale** `.build/headers/…/TraceRecordingState.h` is correctly ignored — the composed `TraceRecordingState.h`/`HostTracingProfile.h` come from source, and other headers + module maps/umbrellas are unaffected (structural gate passes). - Guard: composed layout with a sentinel header → `verifyVersionStamp` throws listing the offending files; stamped → `version stamp OK (N copies checked)`; no effect without the flag. - Verified against a fresh RN-nightly app + `react-native-unistyles@3.3.0` on Xcode 26.3 (prebuilt mode) and in the Expo prebuilt harness (26.3 + 26.6): stock prebuilt headers reproduce the `shadowNodeFromValue` error; the stamped prebuilt header resolves it. - End-to-end proof is the next nightly run: the composed tarball must carry a stamped header. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed By: javache Differential Revision: D113005220 Pulled By: cipolleschi fbshipit-source-id: 5fbba8bb4e84fd1458a2f4a0baa623cf613b6e3b |
||
|
|
6aa147f6c9 |
feat(iOS): ReactNativeDependenciesHeaders sidecar + pure-RN ReactNativeHeaders, published to Maven (#57442)
Summary: Step 2 of the prebuilt-deps roadmap: ship the deps headers as a **SwiftPM-ready, self-contained artifact** and make every header namespace have exactly **one physical home**. 1. **New artifact: `ReactNativeDependenciesHeaders.xcframework`** — the binary `ReactNativeDependencies.xcframework` is framework-type, so its root `Headers/` is invisible to SwiftPM binaryTargets (`HeadersPath` is rejected on framework entries; verified empirically). The deps prebuild now emits a headers-only library-type sidecar (stub archives + per-slice `Headers/` + `HeadersPath` — the exact `ReactNativeHeaders` recipe, factored into a shared `headers-xcframework.js` emitter) carrying all seven deps namespaces incl. SocketRocket, with slice parity derived from the binary artifact's Info.plist. Ships inside the deps tarball *and* standalone. 2. **`ReactNativeHeaders` goes pure-RN** — the R2 relocation of deps namespaces (and the `DEPS_NAMESPACES_NOT_RELOCATED` SocketRocket exclusion list) is deleted. Relocated copies are what enabled the SocketRocket dual-copy regression (duplicate `interface` / poisoned module graph under `use_frameworks!`); that bug class is now structurally impossible. Headers gate flipped: deps namespaces must be **absent** from RNH; the sidecar emitter enforces set-equality with `DEPS_NAMESPACES` fail-closed in both directions. On the CocoaPods side, a new `ReactNativeDependenciesUtils.configure_aggregate_xcconfig` injects the deps pod's `Headers/` globally (aggregate + every pod target), mirroring the rncore injection — this replaces the folly/glog resolution pods previously got via the flattened `React-Core-prebuilt/Headers`. 3. **CI: prebuilt + dynamic-frameworks lane** — the regression's exact config had no coverage (the `test-ios-rntester` action hard-coupled `use-frameworks:true` to source builds). New `use-prebuilds` input; `test_ios_rntester`'s dynamic cells now consume the workflow-built prebuilt artifacts. 4. **Maven publishing** — `ReactNativeHeaders` and `ReactNativeDependenciesHeaders` publish standalone on `react-native-artifacts` (classifiers `reactnative-headers-*`, `reactnative-dependencies-headers-*`); `verifyArtifactsAreOnMaven` now HEAD-checks every classifier tarball instead of only the POM. Stacked on https://github.com/react/react-native/issues/57440. The SwiftPM preview (https://github.com/react/react-native/issues/57332) rebases on top and wires the sidecar as its 5th binaryTarget. ## Changelog: [IOS] [CHANGED] - Prebuilt artifacts: ReactNativeHeaders is pure-RN; third-party deps headers ship in the new ReactNativeDependenciesHeaders.xcframework sidecar (and the ReactNativeDependencies pod), published standalone to Maven Pull Request resolved: https://github.com/react/react-native/pull/57442 Test Plan: - Headers gate: include-health, structural (deps absent from RNH, byte-matched module maps), and compile smokes (React module + 14 namespace modules + Expo-shape ObjC++/Swift fixtures vs the deps include path) — ALL PASSED - jest: 33/33 (`scripts/ios-prebuild/__tests__`, incl. new sidecar set-equality tests) - ESLint (`--max-warnings 0`), Prettier, Flow (`yarn flow-check`): clean - E2E (locally built artifacts): rn-tester prebuilt static ✅, prebuilt `USE_FRAMEWORKS=dynamic` ✅ (the regression config — verified `React-Core-prebuilt/Headers` contains no deps namespaces and the deps pod serves all seven), helloworld static ✅, source-core + prebuilt-deps ✅ (React compiled from source resolves folly via the deps pod), source-mode control with unchanged dependency graph ✅ - Sidecar inspected: per-slice `HeadersPath`, 7 namespaces, slice parity with the binary - Publication validated end-to-end with `publishReleasePublicationToMavenLocal`: all 12 files + POM land with the expected classifier names 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed By: fabriziocucci Differential Revision: D111449462 Pulled By: cipolleschi fbshipit-source-id: e1217d14c0588d00a207622d346c9e6f4705a95d |
||
|
|
376bd0e464 |
refactor(ios): remove clang VFS overlay, resolve headers via new ReactNativeHeaders framework (#57285)
Summary: The prebuilt `React.xcframework` previously relied on a Clang VFS overlay (`React-VFS.yaml`) to make headers importable, because the headers were laid out in CocoaPods-style namespaced folders rather than standard framework conventions. The overlay had to be generated at build time, re-resolved at pod-install time per slice, and injected as `-ivfsoverlay` flags into every Obj-C, C++, and Swift compile (including aggregate and third-party pod targets). This is fragile, hard to reason about, and incompatible with SwiftPM consumption. This PR removes the VFS overlay entirely and resolves headers through standard framework/header-search-path mechanics instead. **Headers are now emitted into the artifact according to an explicit, executable spec:** - **`React.xcframework`** — each slice's `React.framework` carries every `<React/...>` header plus a framework module map, so `#import <React/...>` and `import React` resolve through `FRAMEWORK_SEARCH_PATHS` automatically. - **`ReactNativeHeaders.xcframework`** (new, headers-only) — carries every other namespace (`<react/...>`, `<yoga/...>`, `folly`, `glog`, …), shipped alongside in the prebuilt tarball and exposed via a single header search path. - This makes `ReactNativeDependencies` binary-only. No clang VFS overlay, no per-target `-ivfsoverlay` flags. The layout is driven by a single source of truth (`headers-spec.js`, rules R1–R11) that both the prebuild compose step and downstream SwiftPM tooling derive from, so the shipped header set cannot drift from the spec. Source headers are byte-identical to the repo — the only consumer-facing change needed is bare-form angle includes (`#import <RCTAppDelegate.h>` → `#import <React/RCTAppDelegate.h>`). **Consumer surfaces the flattened layout initially dropped are restored** (validated against Expo and community Fabric modules): - Private headers (`RCTBridge+Private.h` + the Fabric `RCTComponentView*` family) are exposed in the `React` module map — modular where safe, `textual` where they reach C++ — so frameworks like Expo compile unchanged, incl. Swift access to `RCTBridge.moduleRegistry`. - `React_RCTAppDelegate-umbrella.h` is re-emitted (derived from the live header set) for consumers probing it via `__has_include`. - Sources shipping under multiple include spellings (`React/X.h` + legacy `CoreModules/…`, `RCTImage/…`, bare aliases — 116 today) keep content at ONE module-owned spelling; other spellings become generated redirect shims, so `-fmodules` consumers cannot hit duplicate declarations. - The `React-RCTFabric` facade re-vends `RCTFabricComponentsPlugins.h` at `header_dir "React"`, keeping community Fabric modules' quoted `#import "RCTFabricComponentsPlugins.h"` working as with source pods. **The layout is verified at generator time** (`headers-verify.js`, runs in the prebuild compose CI job): unresolvable includes ratchet against a committed baseline, composed module maps/umbrellas must byte-match the spec render, and consumer-shaped compile smokes must pass (the `React` module, every namespace module, an Expo-shaped ObjC++ fixture, and a Swift `moduleRegistry` fixture). Fail-closed guards cover header collisions, allowlist drift, and missing OR undeclared third-party deps namespaces (the latter surfaced `SocketRocket`, which is deliberately NOT relocated — the real pod vends it, and textual copies collide under `use_frameworks`; the gate asserts its absence). **Key changes** - **New**: `headers-spec.js` (the executable layout contract, R1–R11), `headers-compose.js` (emitter for both xcframeworks), `headers-inventory.js` (podspec-driven header classifier feeding the spec + a diagnostic manifest), `headers-verify.js` (generator-time gate + CI step), `__docs__/headers-rules.md` (rules + rationale). - **Removed**: `vfs.js`, VFS types in `types.js`, and the VFS processing/flag-injection paths in `rncore.rb` and `xcframework.js`. - **Updated**: `React-Core-prebuilt.podspec` (vends both xcframeworks, flattens `ReactNativeHeaders` headers into `Headers/` via `prepare_command`, fails closed on incomplete tarballs), `rncore.rb` / `react_native_pods.rb` (header search path instead of overlay flags), `prebuild-ios-core.yml` (core tarball ships both xcframeworks; compose job verifies the composed headers), README (VFS docs replaced with the new model). - Added facades to the Podspecs that shouldn't be in use when running using precompiled frameworks to satisfy dependencies as empty pod-specs (with the single `RCTFabricComponentsPlugins.h` re-vend exception noted above). ## Changelog: [IOS] [CHANGED] - Remove the Clang VFS overlay from prebuilt React Native Core; resolve headers via React.xcframework + a new headers-only ReactNativeHeaders.xcframework Pull Request resolved: https://github.com/react/react-native/pull/57285 Test Plan: - [x] rn-tester builds against the prebuilt `React-Core-prebuilt` pod (Debug + Release) with no `-ivfsoverlay` flags present in the generated xcconfigs. - [x] rn-tester builds against React native source code (without any prebuilt artifacts) - [x] `#import <React/...>`, `import React;`, and the relocated namespaces (`<react/...>`, `<yoga/...>`, `folly`/`glog`) all resolve. - [x] Prebuilt tarball contains both `React.xcframework` and `ReactNativeHeaders.xcframework`; pod install flattens headers into `React-Core-prebuilt/Headers`. - [x] Switch RN-tester between Debug/Release and verify that both `React.xcframework` and `ReactNativeHeaders.xcframework` are changed between debug and release correctly. - [x] `headers-verify.js` gate green on Debug and Release composes (`-Werror=non-modular-include-in-framework-module` never trips in consumer builds). - [x] `private/helloworld` builds against the prebuilt core (CocoaPods path). - [x] Expo SDK compiles against the prebuilt artifacts (private headers, `React_RCTAppDelegate` umbrella probe, Fabric quoted imports). Reviewed By: fabriziocucci Differential Revision: D111448598 Pulled By: cipolleschi fbshipit-source-id: 72bc2f37765ad425722161a038e410ba976858a5 |
||
|
|
0ed6c560da |
Consolidate package checks into one Jest test (#57509)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57509 Simplify/unify various mechanisms for the monorepo's package invariants. These checks were previously scattered: - `private/monorepo-tests` package (manifest field checks) - `.github/workflow-scripts/lint_files.sh` (`.npmignore` ban) - `react-native/eslint-plugin-monorepo` (manifest field checks — duplicated) This folds everything into `scripts/monorepo-tests/__tests__/check-packages-test.js`. A plain Jest test is the most extensible home for future checks. Changelog: [Internal] Reviewed By: cortinico Differential Revision: D111471313 fbshipit-source-id: ea50abd8148d92e70605dd7f809654348e3c0080 |
||
|
|
c948b61c05 |
Enable Strict TS API by default (#57490)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57490 See [**RFC0894: Removing deep imports from react-native**](https://github.com/react-native-community/discussions-and-proposals/pull/894) This is the **big switch** to enable the Strict TypeScript API (generated types + single index entry point) by default in React Native. **Opt-in → opt-out** After this change, the main `react-native` package resolves its `"types"` entry points only to `types_generated/index.d.ts` — with no other subpaths available. The new `"react-native-legacy-deep-imports"` condition maps to legacy `types/` and `Libraries/*.d.ts` sources. **Impact limitation**: For this stage of rollout, the `"default"` condition continues to resolve to source files. Only TypeScript is affected. **How to opt out** Opposite of today's opt-in, which we will update in [the docs](https://reactnative.dev/docs/strict-typescript-api). Again, the only impact area today is **TypeScript**. ```json5 // tsconfig.json { "extends": "react-native/typescript-config", "compilerOptions": { ... "customConditions": ["react-native-legacy-deep-imports"] } } ``` **Other changes** - Drop `react-native/typescript-config/strict` entry point, update README. - Update `__typetests__`. **Rollout plan** **Target release: 0.87**. This and the contributing stack will be cherry picked for RC1. - We've conducted testing against 100+ real Expo codebases, giving us the confidence that we've reduced breaking changes enough that the vast majority of RN codebases can migrate. - The Strict API includes a number of **intentional breaking changes**, and docs have been kept up to date. - We're shipping a `/migrate-to-strict-api` skill to migrate via agents, see https://github.com/react-native-community/skills/pull/3. **What's improved since 0.80?** Since the initial opt-in launch of the Strict API in 0.80, we've been making continuous improvements over the last year to get our generated types into a widely launchable state. Most notably: - 21+ new/updated root APIs and fixes due to community feedback ([discussion](https://github.com/react-native-community/discussions-and-proposals/discussions/893), [PRs](https://github.com/react/react-native/pulls?q=is%3Apr%20label%3A%22JS%20API%20stabilization%20(1.0)%22%20is%3Aclosed)). - Upstream encapsulation blocker in TypeScript, fixed in 6.0 (https://github.com/react/react-native/issues/53565). - Tailwind/Uniwind compatibility (`interface` types for props). - `*Instance` ref type exports for all built-in components (https://github.com/react-native-community/discussions-and-proposals/pull/1003). - Fixes to previously mistyped, high impact APIs, such as `Appearance`. - New subpath entry points for `asset-registry`, `setup-env`, and others. - Refinements to doc comments/type translation build. **Rollback plan** Revert this diff. IMPORTANT: We'll adopt a policy of **super-eager rollback**, if there are any unsolvable issues during the RC phase. Changelog: [General][Breaking] - React Native's default JavaScript API is now the [Strict TypeScript API](https://reactnative.dev/docs/strict-typescript-api). Use `customConditions: ["react-native-legacy-deep-imports"]` to opt out. Reviewed By: cortinico Differential Revision: D110458670 fbshipit-source-id: 4b0e0b458a5f895f783d6d936e7b11ccff2df076 |
||
|
|
c080619353 |
Fix skipped post-publish jobs in release mode (#57479)
Summary: During the 0.87.0-rc.0 release, the npm packages published successfully (`publish_react_native` ✓) but every release-only downstream job was **skipped**: `post_publish`, `generate_changelog`, `bump_podfile_lock`, and `create_draft_release`. As a result the community template was not published, rn-diff-purge was not triggered, npm/Maven verification did not run, the changelog was not generated, `Podfile.lock` was not bumped, and no draft GitHub release was created. ### Root cause These four jobs gate on a bare condition: ```yaml if: needs.determine_mode.outputs.mode == 'release' ``` Because that expression contains no status-check function, GitHub Actions implicitly ANDs a `success()` gate. `success()` evaluates to false when there is a **skipped job in the dependency graph**. In release mode, `build_android` (a dependency of `publish_react_native`) is always skipped, which poisons the implicit `success()` for these downstream jobs — so they skip even after a fully successful publish. `publish_react_native` already works around exactly this with `always()` + explicit `.result == 'success'` checks (see its existing `if:` and comment). This PR applies the same, proven pattern to the four downstream jobs. ### Fix Replace each bare `if:` with `always()` plus explicit result checks so the jobs run whenever the release publish actually succeeds, and only in release mode: ```yaml if: | always() && needs.determine_mode.result == 'success' && needs.publish_react_native.result == 'success' && needs.determine_mode.outputs.mode == 'release' ``` (`create_draft_release` checks `generate_changelog` and `set_hermes_version` instead, matching its `needs`.) ## Changelog: [Internal] - ### Notes - This bug is structural — it affects **every** release, not just rc.0, since `build_android` is always skipped in release mode. - A companion PR backports this fix to `0.87-stable`. Pull Request resolved: https://github.com/react/react-native/pull/57479 Test Plan: - `if` expressions unchanged in intent: run only for a successful release publish, skip for nightly/bumped-packages. - YAML validated locally. - Verify on the next release that `post_publish`, `generate_changelog`, `bump_podfile_lock`, and `create_draft_release` all run after `publish_react_native` succeeds. Reviewed By: cortinico Differential Revision: D111035339 Pulled By: cipolleschi fbshipit-source-id: ce26ef974909af85087dcba263430e5e3ec7b990 |
||
|
|
05577d42d6 |
Add image smoke-test examples and Maestro flows to RNTester (#57306)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57306 Adds three Image examples to RNTester plus matching Maestro end-to-end flows, covering image-loading behaviors that previously had little or no RNTester coverage: - Progressive JPEG (`progressiveRenderingEnabled`) - `blurRadius` combined with `Image.prefetch` (blur postprocessor over a prefetched bitmap) - Wide-gamut (Display-P3) vs sRGB and alpha transparency Each example renders status text (load/error) with stable testIDs so the Maestro flows can assert behavior; the visual cases also capture screenshots. Progressive JPEG is gated to Android (the prop is Android-only); the rest run on both platforms. Changelog: [Internal] Reviewed By: cortinico Differential Revision: D109316705 fbshipit-source-id: 922dfcf22a4a8ec54722a41524cd6c3039e1ada8 |
||
|
|
fa371d156d |
Add macOS 26 icon for RNDT (#57310)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57310 Add `AppIcon.icon` file (Icon Composer) for macOS 26 Tahoe. Also rename previous `.icns` file for consistency. `electron/packager` is updated to `^20.0.0` (`.icon` support was added in `18.4.0`). **Notes** - This change ensures the Icon Composer source is part of the codebase (following above Electron packager support which came in March). Changelog: [General][Changed] - **React Native DevTools**: Add macOS 26/27 app icon Reviewed By: robhogan Differential Revision: D97292364 fbshipit-source-id: ba1c34175a95da8c2860142d9db0c4d98d3f6de0 |
||
|
|
19c11baf4d |
Revert "Unbreak android CI by moving to ubuntu-latest (#57216)" (#57323)
Summary: This reverts the runner changes from https://github.com/react/react-native/issues/57216, which moved the Android CI jobs from the dedicated `4-core-ubuntu` / `8-core-ubuntu` runners onto the standard `ubuntu-latest` runners. I'm opening this (as a draft) to **see if we can speed up the RN runners** — i.e. to measure whether going back to the larger dedicated runners gives us faster CI than `ubuntu-latest`. This is an experiment to compare timings. ### What's reverted - `e2e-android-rntester.yml`: `ubuntu-latest` → `4-core-ubuntu` - `e2e-android-templateapp.yml`: `ubuntu-latest` → `4-core-ubuntu` - `fantom-tests.yml`: `ubuntu-latest` → `8-core-ubuntu` - `test-all.yml`: `build_fantom_runner`, `build_android`, `build_npm_package` → `8-core-ubuntu`; `test_android_helloworld` → `4-core-ubuntu` ### Not reverted (drift since https://github.com/react/react-native/issues/57216) - `nightly.yml` was deleted on main (consolidated into `publish-npm.yml`). - `publish-npm.yml` was fully restructured on main (the old `publish-react-native` reusable job no longer exists). These two are release/nightly jobs rather than the per-PR CI that determines runner speed, so they're intentionally left untouched. Changelog: [INTERNAL] - ## Changelog [INTERNAL] - Pull Request resolved: https://github.com/react/react-native/pull/57323 Test Plan: CI — compare job durations against `ubuntu-latest`. Reviewed By: fabriziocucci Differential Revision: D109808150 Pulled By: cortinico fbshipit-source-id: 694eba516f0d42ef733e729b23534f09dfe8548c |
||
|
|
dc4d5e8ada |
Bump Maestro CI version to 2.6.1 for rn-tester e2e (#57307)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57307 Bumps `MAESTRO_VERSION` from `1.40.0` to `2.6.1` so we can use the new the visual-regression `assertScreenshot` command. The two Maestro 2.0.0 breaking changes are already satisfied: JDK 17 is set up in both actions (`actions/setup-java@v5`), and the flows use only plain `${...}` variable interpolation rather than the JS scripting affected by the Rhino -> GraalJS engine swap. Changelog: [Internal] Reviewed By: christophpurrer Differential Revision: D109359976 fbshipit-source-id: 78377a8dadaaee5d316513adc47d56a2b9b4dc40 |
||
|
|
c6110b1a3f |
GH workflows - remove temporary debugging output now trusted publish is working (#57287)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57287 Just tidying up some temporary output we no longer need. Changelog: [Internal] ___ Reviewed By: cortinico Differential Revision: D109152147 fbshipit-source-id: 812fec3bbf09712b7e7959282e8c3711d84b7e96 |
||
|
|
738839c0dd |
Apply prettier to .yml files + consistent quote style (#57286)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57286 We currently have a mix of quote styles in `.yml` files (AI summary below). This applies prettier and reformats everything to single quotes to align with defaults. Also fixes a couple of cases of over-indentation. ``` Single-quotes only (0 double-quoted scalars): analyze-pr.yml — 12 single, 0 double api-changes.yml — 3 single, 0 double check-for-reproducer.yml — 4 single, 0 double retry-workflow.yml — 1 single, 0 double Single-quote predominant > double: autorebase.yml 2 vs 1 create-draft-release.yml 8 vs 2 generate-changelog.yml 3 vs 2 on-issue-labeled.yml 7 vs 2 prebuild-ios-core.yml 59 vs 17 prebuild-ios-dependencies.yml 39 vs 1 stale-bot.yml 18 vs 15 test-all.yml 70 vs 27 Double-quote predominant > single: bump-podfile-lock.yml 1 vs 10 create-release.yml 3 vs 12 e2e-android-rntester.yml 2 vs 6 e2e-android-templateapp.yml 6 vs 13 e2e-ios-rntester.yml 2 vs 7 e2e-ios-templateapp.yml 2 vs 18 fantom-tests.yml 2 vs 7 monitor-new-issues.yml 3 vs 12 publish-npm.yml 42 vs 50 validate-cxx-api-snapshots.yml 2 vs 23 validate-dotslash-artifacts.yml 2 vs 5 Tie / 1-1: cache-reaper.yml 1 vs 1 close-pr.yml 1 vs 1 needs-attention.yml 2 vs 2 All files contain single quotes somewhere, but only those 4 are single-quote-exclusive. Most CI-heavy workflows — bump, create-release, e2e-, fantom, monitor, publish-npm, validate- — lean double-quoted, while the pr/issue automation, prebuild ios, test-all, and stale-bot lean single-quoted. ``` Changelog: [Internal] ___ Differential Revision: D109151683 fbshipit-source-id: 24391e906c0dd92fe402224089dce8bb2068b4d9 |
||
|
|
65bdf26083 |
Run npm publish with Node 24 / npm 11.5 for trusted publish support (#57269)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57269 Trusted publish support requires `npm` CLI version >=11.5.1 ([docs](https://docs.npmjs.com/trusted-publishers)), which is bundled with Node 24. This bumps the Node version for just those jobs that call `npm publish`. Changelog: [Internal] Reviewed By: fabriziocucci Differential Revision: D109009971 fbshipit-source-id: 6e7f412c6da0e5e5749a29e789f8c2e67610d7b0 |
||
|
|
567b9f0aa1 |
Fix OIDC publish, unify top-level package-publishing workflows (#57255)
Summary: ## Problem npm Trusted Publishing matches the `workflow_ref` OIDC claim, which is always the top-level workflow filename. npm allows only ONE trusted publisher per package. The prior migration (https://github.com/react/react-native/issues/57099) used `workflow_call` to route all publishes through `publish-npm.yml`, but `workflow_ref` resolves to the *caller* (e.g. `nightly.yml`), not the reusable child, so the Trusted Publisher entry for `publish-npm.yml` never matches. ## Solution Merge all three publish entry points into `publish-npm.yml` itself, triggered by all three event types: - `push.tags: v0.*` -> release mode (was publish-release.yml) - `schedule + workflow_dispatch` -> nightly mode (was nightly.yml) - `push.branches: main, *-stable` -> bumped-packages mode (was publish-bumped-packages.yml) A `determine_mode` job inspects the trigger and sets the mode. Downstream jobs use conditional `if:` expressions to run only the relevant build/publish steps. Since `publish-npm.yml` is now always the top-level workflow, `workflow_ref` always resolves to `publish-npm.yml`, which matches what's already configured on npm. Changelog: [Internal] Pull Request resolved: https://github.com/react/react-native/pull/57255 Reviewed By: cortinico Differential Revision: D108894981 Pulled By: robhogan fbshipit-source-id: 743d5b75cbce1eedfec681ec98fd17332f05f14d |
||
|
|
097dbc288b |
Unbreak android CI by moving to ubuntu-latest (#57216)
Summary: build_android is currently timing out - this should unblock it for now till we find a different solution. ## Changelog: [INTERNAL] - Pull Request resolved: https://github.com/react/react-native/pull/57216 Test Plan: CI Reviewed By: huntie Differential Revision: D108744449 Pulled By: cortinico fbshipit-source-id: 4b14252889c3d9ebcb4ad2135839233e103355d7 |
||
|
|
861d8e07a0 |
Update GH Actions references from facebook/react-native to react/react-native (#57167)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57167 Update GitHub Actions workflow files to reflect React Native's migration from `facebook/react-native` to `react/react-native`. Changes the fork-prevention guards (`github.repository == 'facebook/react-native'`) to use the new org across 17 workflow files (28 occurrences total), plus updates the `repo_owner` parameter in the issue monitoring workflow. Changelog: [Internal] Reviewed By: fabriziocucci Differential Revision: D108246445 fbshipit-source-id: 010631838a05e366da525aa765d3ea4376f9d145 |
||
|
|
4ea4db6adf |
Add temporary OIDC claim debugging to npm publish workflow
Summary: Adds a temporary debug step to both jobs of the reusable npm publish workflow that requests the GitHub Actions OIDC token (npm audience) and prints its decoded claims. This makes it possible to compare the token claims against the npm Trusted Publisher configuration when the OIDC exchange fails. Only the decoded claims are printed, never the raw token. Changelog: [Internal] bypass-github-export-checks Reviewed By: cortinico, cipolleschi Differential Revision: D108108630 fbshipit-source-id: 6ae8be8c9e9e2e611b6941b336230a21f876e134 |
||
|
|
40c90ada39 |
fix: allow escape interpretation for shells (#57114)
Summary: This makes the shell to use escape interpretation by setting `echo -e "..."`. For zsh shell, this often works out of the box. For other shells like bash, we may need to set it explicitly. ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [INTERNAL] [FIXED] - allow escape interpretation for shells Pull Request resolved: https://github.com/facebook/react-native/pull/57114 Test Plan: - CI Passes - Verified Locally on template app https://github.com/user-attachments/assets/4c8c6bf7-1cf2-4bd8-b094-651c44578ae0 Reviewed By: cipolleschi Differential Revision: D107904889 Pulled By: cortinico fbshipit-source-id: 2222f589ecc149a82d5067e0a2198b9c1a17ffcb |
||
|
|
8bcfb3ba1c |
Migrate npm publish to OIDC Trusted Publishing via a reusable workflow (#57099)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/57099 Replaces the long-lived `GHA_NPM_TOKEN` automation token with npm Trusted Publishing (OIDC) for every `npm publish` invoked from this repo's GitHub Actions. Why a reusable workflow: npmjs.com Trusted Publishing accepts only ONE (org, repo, workflow_filename, environment) tuple per package. Today, packages are published from multiple workflow files: - `react-native` from publish-release.yml + nightly.yml - every `react-native/*` from nightly.yml + publish-bumped-packages.yml A naive per-workflow OIDC migration would require two Trusted Publisher entries per package, which npm doesn't support. Instead, this diff funnels every `npm publish` through one new file — `.github/workflows/publish-npm.yml` — invoked via `workflow_call` from the existing top-level workflows. The OIDC `job_workflow_ref` claim therefore always resolves to `publish-npm.yml`, so each package needs exactly one Trusted Publisher entry pointing here. What changes: * New `.github/workflows/publish-npm.yml`: reusable workflow with a `mode` input. `mode: react-native` runs the full Android + iOS prebuilt + JS build path (used by release & nightly, publishes `react-native` and — in nightly mode — every `react-native/*` package via `scripts/releases-ci/publish-npm.js`). `mode: monorepo-packages` runs only the JS build and publishes the delta-bumped packages via `scripts/releases-ci/publish-updated-packages.js` (used by publish-bumped-packages.yml). Both jobs grant `id-token: write` so the npm CLI can mint the OIDC token for Trusted Publishing. * `.github/workflows/publish-release.yml`: replace the `build_npm_package` job's inline build/publish steps with a `uses: ./.github/workflows/publish-npm.yml` call. The template-publish, rn-diff-purge, npm-verify, and Maven-verify steps move into a new `post_publish` follow-up job that `needs: [build_npm_package]`. Drops `GHA_NPM_TOKEN` from the env. * `.github/workflows/nightly.yml`: same — `build_npm_package` now delegates to the reusable workflow. Drops `GHA_NPM_TOKEN` and the obsolete `Verify NPM token` precheck (Trusted Publishing has no pre-mintable token to validate; failures surface at `npm publish` time). * `.github/workflows/publish-bumped-packages.yml`: shrinks to a thin trigger wrapper that calls the reusable workflow with `mode: monorepo-packages`. * `.github/workflows/create-release.yml`: drop the obsolete `Verify NPM token` step. * `.github/actions/build-npm-package`: drop the `gha-npm-token` input and the `Set npm credentials` step that wrote `_authToken`. Pass `registry-url: https://registry.npmjs.org` to setup-node so `actions/setup-node@v6` writes a `.npmrc` configured to consume the OIDC token at publish time. * `.github/actions/setup-node`: thread a new `registry-url` input through to `actions/setup-node@v6`. The publish scripts themselves (`scripts/releases-ci/publish-npm.js`, `scripts/releases-ci/publish-updated-packages.js`, `scripts/releases/utils/npm-utils.js`) are unchanged: they shell out to plain `npm publish`, which performs the OIDC exchange transparently when it sees a GitHub Actions OIDC environment and a Trusted Publisher configured for the package on npmjs.com. Note: this diff only changes the workflow definitions. Each package on npmjs.com must additionally be configured with a Trusted Publisher pointing at: - org: facebook - repo: react-native - workflow filename: publish-npm.yml - environment: npm-publish The npm CLI's OIDC exchange returns 404 until that registry-side config is in place. Trusted Publisher entries are additive on npmjs.com (don't enable "Require Trusted Publishing" yet) so the existing token-based flow keeps working through the cutover. See the stack landing notes for the full package list and UI steps. Backport: this also needs picking back to `*-stable` branches before "Require Trusted Publishing" is enabled on any package, since GitHub Actions runs the workflow file from the ref that triggers it. Changelog: [Internal] Reviewed By: cortinico, cipolleschi Differential Revision: D107805971 fbshipit-source-id: 7a360dff9666c4b0952504331d26c0af74148789 |
||
|
|
b392035b10 |
fix: add line break to gradle.properties for template testing (#57107)
Summary: This fixes the failing CI jobs on main for `template` testing. The job fails as they echo `react.internal.mavenLocalRepo=...` to the `gradle.properties` of template test project. As a result of which the `gradle.properties` look like below: ```properties android.builtInKotlin=false android.newDsl=falsereact.internal.mavenLocalRepo=... ``` To fix it we add a line break in the `echo` command. ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [INTERNAL] [FIXED] - add line break to gradle.properties for template testing Pull Request resolved: https://github.com/facebook/react-native/pull/57107 Test Plan: - CI Passing - Verified Locally Reviewed By: cortinico Differential Revision: D107880136 Pulled By: cipolleschi fbshipit-source-id: 81cf2fe53c1c2285f79db538aa5aa3cb745f796d |