mirror of
https://github.com/react/react-native.git
synced 2026-09-29 05:43:06 +08:00
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.
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.
[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
(cherry picked from commit 43b44ed7c3)