Skip to content

fix(ci): align Resolve Hermes with HermesV1 / hermesvm.xcframework#2952

Draft
Saadnajmi wants to merge 6 commits intomicrosoft:0.83-mergefrom
Saadnajmi:sanajmi/0.83-resolve-hermesv1
Draft

fix(ci): align Resolve Hermes with HermesV1 / hermesvm.xcframework#2952
Saadnajmi wants to merge 6 commits intomicrosoft:0.83-mergefrom
Saadnajmi:sanajmi/0.83-resolve-hermesv1

Conversation

@Saadnajmi
Copy link
Copy Markdown
Collaborator

Summary

After the 0.83 merge, the SPM consumer (Package.swift, scripts/ios-prebuild/hermes.js) was already migrated to the new HermesV1 product (hermesvm.xcframework), but the Resolve Hermes producer was still V0-shaped:

  • The recompose path in .github/scripts/resolve-hermes.mts operated on hermes.xcframework / hermes.framework.
  • packages/react-native/scripts/ios-prebuild/microsoft-hermes.js resolved Hermes commits against the legacy main branch instead of static_h.
  • The cache key (hermes-v1-…) referred to a cache schema version, not the engine variant — so a stale V0-shaped cache could be re-uploaded under the same artifact name.

The upstream build scripts (sdks/hermes-engine/utils/build-apple-framework.sh, build-ios-framework.sh) have already been migrated upstream to unconditionally produce hermesvm.framework / hermesvm.xcframework, so once the resolve-side names line up, the from-source path should also Just Work for V1.

Changes

  • microsoft-hermes.jshermesCommitAtMergeBase() now clones/inspects Hermes static_h instead of main. Added a small hermesV1Tag() helper that reads sdks/.hermesv1version (returns hermes-v250829098.0.2).
  • resolve-hermes.mts — recompose now operates on hermesvm.xcframework / hermesvm.framework throughout (universal xcframework path, standalone macOS slice path, per-slice scan, temp output name).
  • microsoft-resolve-hermes.yml — cache keys bumped hermes-v1-…hermesv1-engine-… so stale V0-shaped caches don't get reused as V1 artifacts.

Test plan

  • CI: Resolve Hermes job runs cleanly. Either the upstream tarball fast-path returns hermesvm.xcframework after recompose, or the from-source fallback (clones at static_h commit, builds via the upstream scripts) produces a hermesvm.xcframework destroot.
  • CI: downstream Build \${platform} jobs in microsoft-prebuild-macos-core.yml find hermesvm.xcframework at the path Package.swift:51 expects, and compile cleanly across iOS, iOS-sim, macOS, visionOS, visionOS-sim.
  • CI: compose-xcframework produces ReactCoreDebug.xcframework.tar.gz as before.

Out of scope / follow-up

  • V0 SPM support (would require parameterizing the workflow + carrying a V0 build path; upstream build scripts are V1-only). Punted — file separate issue if needed.
  • Tarball URL pattern in resolve-hermes.mts:84 is unchanged. If upstream RN 0.83 publishes the V1 tarball under a different filename, the fast path will 404 and we'll fall through to from-source. First CI run will tell us.
  • Debug+Release matrix.

🤖 Generated with Claude Code

Saadnajmi and others added 6 commits April 28, 2026 11:38
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>
The PR-gate workflow's `branches` filter only matched `main`, `*-stable`, and
`release/*`, so PRs targeting `0.83-merge` skipped every required check —
including the very Resolve-Hermes / Prebuild-macOS-Core jobs we want to
exercise on this branch.

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>
…ntView

The post-merge SPM macOS build failed with `unknown type name 'UIView'`
in iOS-style code introduced upstream (effectiveContentView and the
SwiftUI-based filter path), and with duplicate-declaration errors for
focus/blur/handleCommand/becomeFirstResponder/resignFirstResponder
because the macOS section already provides macOS-specific versions.

- Swap raw UIView */UIColor * for RCTPlatformView */RCTUIColor *
  (compatibility aliases that map to UIView/UIColor on iOS and
  NSView/NSColor on macOS).
- Wrap the iOS-only canBecomeFirstResponder + focus-related responder
  methods in `#if !TARGET_OS_OSX` so they don't collide with the
  macOS implementations and don't break AppKit's responder model
  (NSView uses acceptsFirstResponder).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant