fix(0.83, hermes): resolve hermes from version files instead of merge-base#3011
Merged
Conversation
Saadnajmi
commented
Jul 7, 2026
tido64
approved these changes
Jul 7, 2026
Package.swift and ios-prebuild/hermes.js already reference hermesvm.xcframework (the HermesV1 product introduced in RN 0.83), but the Resolve Hermes job still recomposed hermes.xcframework and resolved Hermes commits on the legacy `main` branch. With the upstream build scripts now unconditionally producing hermesvm, this left the SPM build path internally inconsistent. - microsoft-hermes.js: resolve commits on Hermes `static_h` branch; add `hermesV1Tag()` helper that reads sdks/.hermesv1version - resolve-hermes.mts: recompose hermesvm.xcframework / hermesvm.framework - microsoft-resolve-hermes.yml: bump cache key (hermes-v1- -> hermesv1-engine-) so stale V0-shaped caches aren't reused as V1 artifacts Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
HermesV1's static_h CMakeLists requires CMAKE_BUILD_TYPE to be set; the upstream `build_host_hermesc` helper in build-apple-framework.sh doesn't pass it, so the from-source fallback in Resolve Hermes failed at the hermesc step with "Please set CMAKE_BUILD_TYPE". Invoke cmake directly from the workflow with -DCMAKE_BUILD_TYPE=Release (the host compiler is always built Release for perf, matching configure_apple_framework's behavior in Debug builds of the apple frameworks). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
HermesV1 (static_h) replaces the legacy API/hermes/inspector/ headers with API/hermes/cdp/, so the unconditional cp commands in build_apple_framework and prepare_dest_root_for_ci fail with 'No such file or directory' when building from V1 sources. Guard each copy with compgen so the copy is skipped cleanly when the source directory is empty. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Package.swift links against hermesvm.xcframework (HermesV1) but never defines HERMES_V1_ENABLED, so headers like ReactCommon/hermes/inspector-modern/chrome/Registration.h still try to #include <hermes/inspector/RuntimeAdapter.h> — a legacy header V1 dropped. Set HERMES_V1_ENABLED=1 in the shared cxxSettings (alongside USE_HERMES); this matches what cocoapods/utils.rb does when RCT_HERMES_V1_ENABLED=1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
12bfe36 to
19f6014
Compare
… 0.84 Upstream 0.83-stable defaults to Hermes V0 (sdks/.hermesversion = hermes-v0.14.1); V1 is opt-in via RCT_HERMES_V1_ENABLED and only becomes the default in 0.84 (react#54989, commit bbe02de, not backported to 0.83). The `hermes` -> `hermesvm` product rename, however, already landed in 0.83 (react#53094), so the fork's resolve-hermes.mts genuinely needed to catch up to the new artifact name. Reduce the PR to just that V0-compatible rename catch-up and revert the V1-engine bits to match upstream 0.83: - resolve-hermes.mts: keep hermes.* -> hermesvm.* (needed on 0.83). - Package.swift: drop HERMES_V1_ENABLED define (inherited at 0.84 merge). - microsoft-hermes.js: revert static_h -> main; drop unused hermesV1Tag(). - hermes-utils.rb: revert static_h/main gate back to main (V0). - build-apple-framework.sh: revert inspector-header guard (V0 ships them). - microsoft-resolve-hermes.yml: revert cache-key rename + cmake hermesc change (build_host_hermesc works for V0). Net: 6 files -> 1; the five reverted files now match upstream/0.83-merge. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… coordinate resolve-hermes.mts queried com/facebook/react/react-native-artifacts/<rn-version> for the Hermes tarball, but upstream publishes prebuilt Hermes under com/facebook/hermes/hermes-ios/<HERMES_VERSION> (keyed by the Hermes version, not the react-native version). That coordinate has no Hermes classifier, so the download always 404'd and every 0.83 Resolve Hermes run fell back to an expensive from-source build. Point the download at upstream's real coordinate and read the Hermes version from sdks/hermes-engine/version.properties, mirroring the CocoaPods release_tarball_url: HERMES_VERSION_NAME by default (RN 0.83 ships V0 0.14.0), or HERMES_V1_VERSION_NAME when RCT_HERMES_V1_ENABLED=1. The existing recompose step then merges the standalone macOS slice into the universal xcframework. Verified locally end-to-end: - download-hermes Debug -> hermes-ios/0.14.0 (200), recompose -> hermesvm.xcframework with 8 slices incl. macos-arm64_x86_64 (recomposed=true) - RCT_HERMES_V1_ENABLED=1 -> hermes-ios/250829098.0.2 (200) - V0/V1 x debug/release URLs all resolve 200 on repo1.maven.org Result: 0.83 downloads upstream's prebuilt Hermes (on par with RN 0.83's default V0 engine) and no longer builds Hermes from source, so the from-source V1 machinery is unnecessary on 0.83. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The macOS 'resolve Hermes' from-source fallback resolved a Hermes commit from the merge base with facebook/react-native. Now that upstream pins the Hermes version in sdks/.hermesversion (V0) and sdks/.hermesv1version (V1) — files that travel with the RN source — resolve-commit reads the pinned tag (a valid actions/checkout ref) instead. Retires the merge-base heuristic from this path; the from-source fallback jobs are unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…n files Revert scripts/ios-prebuild/hermes.js fully to upstream (facebook/0.83-stable), removing the fork's [macOS] Hermes machinery: the RN-version mapping, the build-from-hermes-commit source type, and buildFromHermesCommit. This also removes a latent bug where the react-native version was fed into the Hermes Maven coordinate (com/facebook/hermes/hermes-ios/<ver>), which 404s on 0.83. In macOS CI this path is short-circuited anyway (HERMES_VERSION=prebuilt). In sdks/hermes-engine/hermes-utils.rb, restore podspec_source_build_from_github_main to upstream and delete the [macOS] hermes_commit_at_merge_base helper (plus its now-unused open3/json/tmpdir requires). Hermes resolution on 0.83 stays covered: the release tarball (hermes-ios/0.14.0) serves the prebuilt path, and BUILD_FROM_GITHUB_TAG (sdks/.hermesversion / .hermesv1version) serves from-source. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…t-hermes Deletes hermesCommitAtMergeBase() (and its now-unused abort helper and os/path imports) now that Phases 1-2 removed its callers in resolve-hermes.mts and hermes.js. The RN-version resolvers (findMatchingHermesVersion, findVersionAtMergeBase, getLatestStableVersionFromNPM) are retained — they still key the reactnative-dependencies artifact, which legitimately stays react-native-version-keyed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rewrite the function docstrings to describe what the code does (inputs, outputs, behavior) instead of narrating the change or its relationship to upstream. Drops the "mirrors the CocoaPods podspec", "the fork previously queried ...", and "as of RN 0.83 upstream renamed ..." asides. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Saadnajmi
commented
Jul 9, 2026
Record that the universal hermesvm.xcframework gained a native macOS slice in Hermes V1 250829098.0.15 (facebook/hermes#1971), while the V0 line (0.14.x) does not yet include it — so recompose is still required for the currently pinned versions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
tido64
approved these changes
Jul 10, 2026
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.
Summary
Fixes Hermes resolution for the macOS SPM prebuild on
0.83-merge, and takes the opportunity to delete a bunch of fork-specific resolution code now that upstream ships the version files we need.The bug:
resolve-hermes.mtswas downloading the Hermes tarball fromcom/facebook/react/react-native-artifacts/<rn-version>. Upstream moved Hermes out of there in 0.83 (react#53985) — it now lives atcom/facebook/hermes/hermes-ios/<hermes-version>, keyed off the Hermes version insdks/hermes-engine/version.properties. So the old URL 404s on 0.83 and every Resolve Hermes run quietly fell back to a ~30 min build from source.What's in here
Download from the right place.
resolve-hermes.mtsreadsversion.properties(HERMES_VERSION_NAME, orHERMES_V1_VERSION_NAMEwhenRCT_HERMES_V1_ENABLED=1) and pullscom/facebook/hermes/hermes-ios/<version>, same as the CocoaPods podspec does. Recompose still splices the standalonemacosx/hermesvm.frameworkinto the universal xcframework.Stay on V0 for 0.83. I reverted the from-source V1 bits from the earlier commits (
static_h,CMAKE_BUILD_TYPE, the inspector-header guard, theHERMES_V1_ENABLEDdefine). 0.83 ships V0 (0.14.0) by default; V1-as-default is a 0.84 thing (react#54989, not backported). We pick it up for free at the 0.84 merge.Drop the fork's homegrown resolution. Now that Hermes is pinned in
version.properties+.hermesversion— files that come along with the RN source at merge time — the old merge-base heuristic isn't needed:resolve-commitjust reads the pinned.hermesversion/.hermesv1versiontag (both are real refs in facebook/hermes) instead of cloning Hermes and guessing a commit from the merge-base timestamp.hermes.jsgoes back to being byte-for-byte identical to upstream0.83-stable. That drops the RN-version→Hermes mapping,BUILD_FROM_HERMES_COMMIT, and a latent bug where it fed the RN version into the Hermes coordinate and 404'd.hermes-utils.rb: deletedhermes_commit_at_merge_base, restoredpodspec_source_build_from_github_mainto upstream.microsoft-hermes.js: droppedhermesCommitAtMergeBase. KeptfindMatchingHermesVersion/findVersionAtMergeBase— those are still doing real work forreactnative-dependencies, which upstream still keys by RN version.Net it's about +120/−400 across 5 files.
Checked locally
download-hermes Debug→hermes-ios/0.14.0(200) → recompose →hermesvm.xcframeworkwith 8 slices includingmacos-arm64_x86_64RCT_HERMES_V1_ENABLED=1→hermes-ios/250829098.0.2(200); V0/V1 × debug/release all resolveresolve-commit→hermes-v0.14.0(V0) /hermes-v250829098.0.2(V1)hermes.jsmatches upstream0.83-stable; no merge-base helpers left anywhere;ruby -c+ eslint passOn the recompose: I checked when the macOS slice starts shipping in the universal xcframework natively (so we can eventually delete this step). It first shows up in V1
250829098.0.15(facebook/hermes#1971); the V0 line (0.14.x) doesn't have it yet, so recompose is still needed for both versions we currently pin.Needs CI to confirm
Can't run the CocoaPods/iOS paths locally, so relying on CI for:
recomposed=true(fast path taken, from-source jobs skipped)hermes.jsandhermes-utils.rbrevertsSupersedes
#2952, #2957 (folded in here)