From 73583156fcb8488e1c6d133cbca78ca23437c2b9 Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Mon, 8 Sep 2025 07:16:48 -0700 Subject: [PATCH 1/3] Check value of the Hermes V1 flag instead of whether it's defined (#53637) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53637 Changelog: [ANDROID][FIXED] - Check for the value of the HERMES_V1_ENABLED flag instead of whether it's defined Reviewed By: cortinico Differential Revision: D81920483 fbshipit-source-id: 550ae9fd27f666affe102b1c5c3f51bde7b5923e --- .../src/main/jni/react/hermes/reactexecutor/CMakeLists.txt | 2 +- .../src/main/jni/react/runtime/hermes/jni/CMakeLists.txt | 2 +- .../ReactAndroid/src/main/jni/react/runtime/jni/CMakeLists.txt | 2 +- .../react-native/ReactCommon/hermes/executor/CMakeLists.txt | 2 +- .../ReactCommon/hermes/inspector-modern/CMakeLists.txt | 2 +- packages/react-native/ReactCommon/react/runtime/CMakeLists.txt | 2 +- .../ReactCommon/react/runtime/hermes/CMakeLists.txt | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt b/packages/react-native/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt index a73ab1c5297b..b28df6a8a2fc 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt +++ b/packages/react-native/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt @@ -28,7 +28,7 @@ target_compile_reactnative_options(hermes_executor PRIVATE) if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED) target_compile_options(hermes_executor PRIVATE -DHERMES_ENABLE_DEBUGGER=1) - if (DEFINED HERMES_V1_ENABLED) + if (HERMES_V1_ENABLED) target_compile_options(hermes_executor PRIVATE -DHERMES_V1_ENABLED=1) endif() endif() diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/hermes/jni/CMakeLists.txt b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/hermes/jni/CMakeLists.txt index 42612452f2e2..3ec451152cf2 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/hermes/jni/CMakeLists.txt +++ b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/hermes/jni/CMakeLists.txt @@ -30,7 +30,7 @@ target_compile_reactnative_options(hermesinstancejni PRIVATE) if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED) target_compile_options(hermesinstancejni PRIVATE -DHERMES_ENABLE_DEBUGGER=1) - if (DEFINED HERMES_V1_ENABLED) + if (HERMES_V1_ENABLED) target_compile_options(hermesinstancejni PRIVATE -DHERMES_V1_ENABLED=1) endif() endif () diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/CMakeLists.txt b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/CMakeLists.txt index 8b88a0c2c9e6..5394cb4af015 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/CMakeLists.txt +++ b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/CMakeLists.txt @@ -20,7 +20,7 @@ target_compile_reactnative_options(rninstance PRIVATE) if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED) target_compile_options(rninstance PRIVATE -DHERMES_ENABLE_DEBUGGER=1) - if (DEFINED HERMES_V1_ENABLED) + if (HERMES_V1_ENABLED) target_compile_options(rninstance PRIVATE -DHERMES_V1_ENABLED=1) endif() endif () diff --git a/packages/react-native/ReactCommon/hermes/executor/CMakeLists.txt b/packages/react-native/ReactCommon/hermes/executor/CMakeLists.txt index 741ced76e886..cf991e1729b0 100644 --- a/packages/react-native/ReactCommon/hermes/executor/CMakeLists.txt +++ b/packages/react-native/ReactCommon/hermes/executor/CMakeLists.txt @@ -33,7 +33,7 @@ if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED) -DHERMES_ENABLE_DEBUGGER=1 ) - if (DEFINED HERMES_V1_ENABLED) + if (HERMES_V1_ENABLED) target_compile_options(hermes_executor_common PRIVATE -DHERMES_V1_ENABLED=1) endif() else() diff --git a/packages/react-native/ReactCommon/hermes/inspector-modern/CMakeLists.txt b/packages/react-native/ReactCommon/hermes/inspector-modern/CMakeLists.txt index 43ceec656215..d392615a80e9 100644 --- a/packages/react-native/ReactCommon/hermes/inspector-modern/CMakeLists.txt +++ b/packages/react-native/ReactCommon/hermes/inspector-modern/CMakeLists.txt @@ -24,7 +24,7 @@ if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED) -DHERMES_ENABLE_DEBUGGER=1 ) - if (DEFINED HERMES_V1_ENABLED) + if (HERMES_V1_ENABLED) target_compile_options(hermes_inspector_modern PRIVATE -DHERMES_V1_ENABLED=1) endif() endif() diff --git a/packages/react-native/ReactCommon/react/runtime/CMakeLists.txt b/packages/react-native/ReactCommon/react/runtime/CMakeLists.txt index 3a4e6360d3d8..25927837d9b6 100644 --- a/packages/react-native/ReactCommon/react/runtime/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/runtime/CMakeLists.txt @@ -19,7 +19,7 @@ target_compile_reactnative_options(bridgeless PRIVATE) if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED) target_compile_options(bridgeless PRIVATE -DHERMES_ENABLE_DEBUGGER=1) - if (DEFINED HERMES_V1_ENABLED) + if (HERMES_V1_ENABLED) target_compile_options(bridgeless PRIVATE -DHERMES_V1_ENABLED=1) endif() endif () diff --git a/packages/react-native/ReactCommon/react/runtime/hermes/CMakeLists.txt b/packages/react-native/ReactCommon/react/runtime/hermes/CMakeLists.txt index c5bf10464e08..a237dfed110d 100644 --- a/packages/react-native/ReactCommon/react/runtime/hermes/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/runtime/hermes/CMakeLists.txt @@ -36,7 +36,7 @@ if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED) -DHERMES_ENABLE_DEBUGGER=1 ) - if (DEFINED HERMES_V1_ENABLED) + if (HERMES_V1_ENABLED) target_compile_options(bridgelesshermes PRIVATE -DHERMES_V1_ENABLED=1) endif() endif() From c32302658427d9fda4079e04d2ffd6b2e5ca88b8 Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Wed, 10 Sep 2025 00:51:41 -0700 Subject: [PATCH 2/3] Read Hermes V1 opt-in flag from the app's properties (#53665) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53665 Changelog: [ANDROID][FIXED] - Read the Hermes V1 opt-in flag from the apps properties when building from source Reviewed By: cortinico Differential Revision: D82018545 fbshipit-source-id: f3c6fdbac190f47b6bf6836105d9e0909d8b86ba --- .../com/facebook/react/utils/ProjectUtils.kt | 7 +++++- settings.gradle.kts | 23 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt index 9e2aaeff9d86..f6a147426f1c 100644 --- a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt +++ b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/ProjectUtils.kt @@ -23,6 +23,7 @@ import com.facebook.react.utils.PropertyUtils.SCOPED_USE_THIRD_PARTY_JSC import com.facebook.react.utils.PropertyUtils.USE_THIRD_PARTY_JSC import org.gradle.api.Project import org.gradle.api.file.DirectoryProperty +import org.jetbrains.kotlin.gradle.plugin.extraProperties internal object ProjectUtils { @@ -75,7 +76,11 @@ internal object ProjectUtils { (project.hasProperty(HERMES_V1_ENABLED) && project.property(HERMES_V1_ENABLED).toString().toBoolean()) || (project.hasProperty(SCOPED_HERMES_V1_ENABLED) && - project.property(SCOPED_HERMES_V1_ENABLED).toString().toBoolean()) + project.property(SCOPED_HERMES_V1_ENABLED).toString().toBoolean()) || + (project.extraProperties.has(HERMES_V1_ENABLED) && + project.extraProperties.get(HERMES_V1_ENABLED).toString().toBoolean()) || + (project.extraProperties.has(SCOPED_HERMES_V1_ENABLED) && + project.extraProperties.get(SCOPED_HERMES_V1_ENABLED).toString().toBoolean()) internal fun Project.needsCodegenFromPackageJson(rootProperty: DirectoryProperty): Boolean { val parsedPackageJson = readPackageJsonFile(this, rootProperty) diff --git a/settings.gradle.kts b/settings.gradle.kts index 093b67a812a7..3493bc3954d3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -44,3 +44,26 @@ configure { lockFiles = files("yarn.lock"), ) } + +// Gradle properties defined in `gradle.properties` are not inherited by +// included builds, see https://github.com/gradle/gradle/issues/2534. +// This is a workaround to read the configuration from the consuming project, +// and apply relevant properties to the :react-native project. +buildscript { + val properties = java.util.Properties() + val propertiesToInherit = listOf("hermesV1Enabled", "react.hermesV1Enabled") + + try { + file("../../android/gradle.properties").inputStream().use { properties.load(it) } + + gradle.rootProject { + propertiesToInherit.forEach { property -> + if (properties.containsKey(property)) { + gradle.rootProject.extra.set(property, properties.getProperty(property)) + } + } + } + } catch (e: Exception) { + // fail silently + } +} From c2f514621fe22fa2ed835a1db94bd2e4ad8d28c0 Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Thu, 11 Sep 2025 06:36:23 -0700 Subject: [PATCH 3/3] Use artifacts published from Hermes repository when using Hermes V1 (#53725) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53725 Changelog: [GENERAL][CHANGED] - Changed the coordinates of hermes artifacts when using Hermes V1 Adds a new `version.properties` file to keep which hermes versions should be consumed from Maven once the versions of Hermes and React Native are decoupled. This diff only implements changes necessary for consuming Hermes V1, as we don't want to migrate everything quite yet (0.82). Reviewed By: cortinico Differential Revision: D82204203 fbshipit-source-id: d712257a73f7ba54612a55c1b312416376f28b56 --- build.gradle.kts | 1 + .../kotlin/com/facebook/react/ReactPlugin.kt | 14 +- .../facebook/react/utils/DependencyUtils.kt | 39 ++- .../com/facebook/react/utils/PathUtils.kt | 1 + .../com/facebook/react/utils/PropertyUtils.kt | 8 +- .../react/utils/DependencyUtilsTest.kt | 297 ++++++++++++++++-- .../com/facebook/react/utils/PathUtilsTest.kt | 2 +- .../ReactAndroid/gradle.properties | 1 - .../sdks/hermes-engine/hermes-engine.podspec | 7 +- .../sdks/hermes-engine/version.properties | 1 + 10 files changed, 322 insertions(+), 49 deletions(-) create mode 100644 packages/react-native/sdks/hermes-engine/version.properties diff --git a/build.gradle.kts b/build.gradle.kts index 866560d63884..dff27b28d060 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -135,6 +135,7 @@ if (project.findProperty("react.internal.useHermesNightly")?.toString()?.toBoole configurations.all { resolutionStrategy.dependencySubstitution { substitute(project(":packages:react-native:ReactAndroid:hermes-engine")) + // TODO: T237406039 update coordinates .using(module("com.facebook.react:hermes-android:0.+")) .because("Users opted to use hermes from nightly") } diff --git a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt index b09dc85a52ce..890e61c007d5 100644 --- a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt +++ b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt @@ -55,8 +55,8 @@ class ReactPlugin : Plugin { project, ) - if (project.rootProject.isHermesV1Enabled != rootExtension.hermesV1Enabled.get()) { - rootExtension.hermesV1Enabled.set(project.rootProject.isHermesV1Enabled) + if (project.rootProject.isHermesV1Enabled) { + rootExtension.hermesV1Enabled.set(true) } // App Only Configuration @@ -71,11 +71,11 @@ class ReactPlugin : Plugin { project.afterEvaluate { val reactNativeDir = extension.reactNativeDir.get().asFile val propertiesFile = File(reactNativeDir, "ReactAndroid/gradle.properties") - val versionAndGroupStrings = readVersionAndGroupStrings(propertiesFile) - val hermesV1Enabled = - if (project.rootProject.hasProperty("hermesV1Enabled")) - project.rootProject.findProperty("hermesV1Enabled") == "true" - else false + val hermesVersionPropertiesFile = + File(reactNativeDir, "sdks/hermes-engine/version.properties") + val versionAndGroupStrings = + readVersionAndGroupStrings(propertiesFile, hermesVersionPropertiesFile) + val hermesV1Enabled = rootExtension.hermesV1Enabled.get() configureDependencies(project, versionAndGroupStrings, hermesV1Enabled) configureRepositories(project) } diff --git a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt index 7fc8e1cfc7b4..65ab468a078d 100644 --- a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt +++ b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/DependencyUtils.kt @@ -13,7 +13,7 @@ import com.facebook.react.utils.PropertyUtils.EXCLUSIVE_ENTEPRISE_REPOSITORY import com.facebook.react.utils.PropertyUtils.INCLUDE_JITPACK_REPOSITORY import com.facebook.react.utils.PropertyUtils.INCLUDE_JITPACK_REPOSITORY_DEFAULT import com.facebook.react.utils.PropertyUtils.INTERNAL_HERMES_PUBLISHING_GROUP -import com.facebook.react.utils.PropertyUtils.INTERNAL_HERMES_VERSION_NAME +import com.facebook.react.utils.PropertyUtils.INTERNAL_HERMES_V1_VERSION_NAME import com.facebook.react.utils.PropertyUtils.INTERNAL_REACT_NATIVE_MAVEN_LOCAL_REPO import com.facebook.react.utils.PropertyUtils.INTERNAL_REACT_PUBLISHING_GROUP import com.facebook.react.utils.PropertyUtils.INTERNAL_USE_HERMES_NIGHTLY @@ -31,6 +31,7 @@ internal object DependencyUtils { internal data class Coordinates( val versionString: String, val hermesVersionString: String, + val hermesV1VersionString: String, val reactGroupString: String = DEFAULT_INTERNAL_REACT_PUBLISHING_GROUP, val hermesGroupString: String = DEFAULT_INTERNAL_HERMES_PUBLISHING_GROUP, ) @@ -113,7 +114,12 @@ internal object DependencyUtils { coordinates: Coordinates, hermesV1Enabled: Boolean = false, ) { - if (coordinates.versionString.isBlank() || coordinates.hermesVersionString.isBlank()) return + if ( + coordinates.versionString.isBlank() || + (!hermesV1Enabled && coordinates.hermesVersionString.isBlank()) || + (hermesV1Enabled && coordinates.hermesV1VersionString.isBlank()) + ) + return project.rootProject.allprojects { eachProject -> eachProject.configurations.all { configuration -> // Here we set a dependencySubstitution for both react-native and hermes-engine as those @@ -133,7 +139,11 @@ internal object DependencyUtils { // Contributors only: The hermes-engine version is forced only if the user has // not opted into using nightlies for local development. configuration.resolutionStrategy.force( - "${coordinates.reactGroupString}:hermes-android:${coordinates.versionString}" + // TODO: T237406039 update coordinates + if (hermesV1Enabled) + "${coordinates.hermesGroupString}:hermes-android:${coordinates.hermesV1VersionString}" + else + "${coordinates.reactGroupString}:hermes-android:${coordinates.hermesVersionString}" ) } } @@ -146,10 +156,11 @@ internal object DependencyUtils { ): List> { // TODO: T231755027 update coordinates and versioning val dependencySubstitution = mutableListOf>() + // TODO: T237406039 update coordinates val hermesVersionString = if (hermesV1Enabled) - "${coordinates.hermesGroupString}:hermes-android:${coordinates.versionString}" - else "${coordinates.reactGroupString}:hermes-android:${coordinates.versionString}" + "${coordinates.hermesGroupString}:hermes-android:${coordinates.hermesV1VersionString}" + else "${coordinates.reactGroupString}:hermes-android:${coordinates.hermesVersionString}" dependencySubstitution.add( Triple( "com.facebook.react:react-native", @@ -172,6 +183,7 @@ internal object DependencyUtils { "The react-android dependency was modified to use the correct Maven group.", ) ) + // TODO: T237406039 update coordinates dependencySubstitution.add( Triple( "com.facebook.react:hermes-android", @@ -183,14 +195,10 @@ internal object DependencyUtils { return dependencySubstitution } - fun readVersionAndGroupStrings(propertiesFile: File): Coordinates { + fun readVersionAndGroupStrings(propertiesFile: File, hermesVersionFile: File): Coordinates { val reactAndroidProperties = Properties() propertiesFile.inputStream().use { reactAndroidProperties.load(it) } val versionStringFromFile = (reactAndroidProperties[INTERNAL_VERSION_NAME] as? String).orEmpty() - // TODO: T231755027 update HERMES_VERSION_NAME in gradle.properties to point to the correct - // hermes version - val hermesVersionStringFromFile = - (reactAndroidProperties[INTERNAL_HERMES_VERSION_NAME] as? String).orEmpty() // If on a nightly, we need to fetch the -SNAPSHOT artifact from Sonatype. val versionString = if (versionStringFromFile.startsWith("0.0.0") || "-nightly-" in versionStringFromFile) { @@ -205,9 +213,18 @@ internal object DependencyUtils { val hermesGroupString = reactAndroidProperties[INTERNAL_HERMES_PUBLISHING_GROUP] as? String ?: DEFAULT_INTERNAL_HERMES_PUBLISHING_GROUP + // TODO: T237406039 read both versions from the same file + val hermesVersionProperties = Properties() + hermesVersionFile.inputStream().use { hermesVersionProperties.load(it) } + + val hermesVersion = versionString + val hermesV1Version = + (hermesVersionProperties[INTERNAL_HERMES_V1_VERSION_NAME] as? String).orEmpty() + return Coordinates( versionString, - hermesVersionStringFromFile, + hermesVersion, + hermesV1Version, reactGroupString, hermesGroupString, ) diff --git a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PathUtils.kt b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PathUtils.kt index e8f5a427c56d..c463292d8810 100644 --- a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PathUtils.kt +++ b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PathUtils.kt @@ -153,6 +153,7 @@ internal fun detectOSAwareHermesCommand( // 3. If Hermes V1 is enabled, use hermes-compiler from npm, otherwise, if the // react-native contains a pre-built hermesc, use it. + // TODO: T237406039 use hermes-compiler from npm for both val hermesCPath = if (hermesV1Enabled) HERMES_COMPILER_NPM_DIR else HERMESC_IN_REACT_NATIVE_DIR val prebuiltHermesPath = hermesCPath diff --git a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PropertyUtils.kt b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PropertyUtils.kt index f2d89ee0c82e..8f7e4928a81e 100644 --- a/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PropertyUtils.kt +++ b/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PropertyUtils.kt @@ -79,6 +79,10 @@ object PropertyUtils { /** Internal property used to control the version name of React Native */ const val INTERNAL_VERSION_NAME = "VERSION_NAME" - /** Internal property used to control the version name of Hermes Engine */ - const val INTERNAL_HERMES_VERSION_NAME = "HERMES_VERSION_NAME" + + /** + * Internal property, shared with iOS, used to control the version name of Hermes Engine. This is + * stored in sdks/hermes-engine/version.properties + */ + const val INTERNAL_HERMES_V1_VERSION_NAME = "HERMES_V1_VERSION_NAME" } diff --git a/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt b/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt index f45435a23864..a1007b708b0d 100644 --- a/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt +++ b/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt @@ -271,54 +271,69 @@ class DependencyUtilsTest { .isEqualTo(2) } - // TODO: T236767053 - @Test fun configureDependencies_withEmptyVersion_doesNothing() { val project = createProject() - configureDependencies(project, DependencyUtils.Coordinates("", "")) + configureDependencies(project, DependencyUtils.Coordinates("", "", "")) assertThat(project.configurations.first().resolutionStrategy.forcedModules.isEmpty()).isTrue() } @Test - fun configureDependencies_withVersionString_appliesResolutionStrategy() { + fun configureDependencies_withVersionString_appliesResolutionStrategy_withClassicHermes() { + val project = createProject() + + configureDependencies(project, DependencyUtils.Coordinates("1.2.3", "4.5.6", "7.8.9")) + + val forcedModules = project.configurations.first().resolutionStrategy.forcedModules + assertThat(forcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" }) + .isTrue() + assertThat(forcedModules.any { it.toString() == "com.facebook.react:hermes-android:4.5.6" }) + .isTrue() + } + + @Test + fun configureDependencies_withVersionString_appliesResolutionStrategy_withHermesV1() { val project = createProject() - configureDependencies(project, DependencyUtils.Coordinates("1.2.3", "1.2.3")) + configureDependencies( + project, + DependencyUtils.Coordinates("1.2.3", "4.5.6", "7.8.9"), + hermesV1Enabled = true, + ) val forcedModules = project.configurations.first().resolutionStrategy.forcedModules assertThat(forcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" }) .isTrue() - assertThat(forcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" }) + assertThat(forcedModules.any { it.toString() == "com.facebook.hermes:hermes-android:7.8.9" }) .isTrue() } @Test - fun configureDependencies_withVersionString_appliesOnAllProjects() { + fun configureDependencies_withVersionString_appliesOnAllProjects_withClassicHermes() { val rootProject = ProjectBuilder.builder().build() val appProject = ProjectBuilder.builder().withName("app").withParent(rootProject).build() val libProject = ProjectBuilder.builder().withName("lib").withParent(rootProject).build() appProject.plugins.apply("com.android.application") libProject.plugins.apply("com.android.library") - configureDependencies(appProject, DependencyUtils.Coordinates("1.2.3", "1.2.3")) + configureDependencies(appProject, DependencyUtils.Coordinates("1.2.3", "4.5.6", "7.8.9")) val appForcedModules = appProject.configurations.first().resolutionStrategy.forcedModules val libForcedModules = libProject.configurations.first().resolutionStrategy.forcedModules assertThat(appForcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" }) .isTrue() - assertThat(appForcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" }) + assertThat(appForcedModules.any { it.toString() == "com.facebook.react:hermes-android:4.5.6" }) .isTrue() assertThat(libForcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" }) .isTrue() - assertThat(libForcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" }) + assertThat(libForcedModules.any { it.toString() == "com.facebook.react:hermes-android:4.5.6" }) .isTrue() } @Test - fun configureDependencies_withVersionStringAndGroupString_appliesOnAllProjects() { + fun configureDependencies_withVersionString_appliesOnAllProjects_withHermesV1() { val rootProject = ProjectBuilder.builder().build() val appProject = ProjectBuilder.builder().withName("app").withParent(rootProject).build() val libProject = ProjectBuilder.builder().withName("lib").withParent(rootProject).build() @@ -327,25 +342,93 @@ class DependencyUtilsTest { configureDependencies( appProject, - DependencyUtils.Coordinates("1.2.3", "1.2.3", "io.github.test"), + DependencyUtils.Coordinates("1.2.3", "4.5.6", "7.8.9"), + hermesV1Enabled = true, + ) + + val appForcedModules = appProject.configurations.first().resolutionStrategy.forcedModules + val libForcedModules = libProject.configurations.first().resolutionStrategy.forcedModules + assertThat(appForcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" }) + .isTrue() + assertThat(appForcedModules.any { it.toString() == "com.facebook.hermes:hermes-android:7.8.9" }) + .isTrue() + assertThat(libForcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" }) + .isTrue() + assertThat(libForcedModules.any { it.toString() == "com.facebook.hermes:hermes-android:7.8.9" }) + .isTrue() + } + + @Test + fun configureDependencies_withVersionStringAndGroupString_appliesOnAllProjects_withClassicHermes() { + val rootProject = ProjectBuilder.builder().build() + val appProject = ProjectBuilder.builder().withName("app").withParent(rootProject).build() + val libProject = ProjectBuilder.builder().withName("lib").withParent(rootProject).build() + appProject.plugins.apply("com.android.application") + libProject.plugins.apply("com.android.library") + + configureDependencies( + appProject, + DependencyUtils.Coordinates( + "1.2.3", + "4.5.6", + "7.8.9", + "io.github.test", + "io.github.test.hermes", + ), ) val appForcedModules = appProject.configurations.first().resolutionStrategy.forcedModules val libForcedModules = libProject.configurations.first().resolutionStrategy.forcedModules assertThat(appForcedModules.any { it.toString() == "io.github.test:react-android:1.2.3" }) .isTrue() - assertThat(appForcedModules.any { it.toString() == "io.github.test:hermes-android:1.2.3" }) + assertThat(appForcedModules.any { it.toString() == "io.github.test:hermes-android:4.5.6" }) .isTrue() assertThat(libForcedModules.any { it.toString() == "io.github.test:react-android:1.2.3" }) .isTrue() - assertThat(libForcedModules.any { it.toString() == "io.github.test:hermes-android:1.2.3" }) + assertThat(libForcedModules.any { it.toString() == "io.github.test:hermes-android:4.5.6" }) .isTrue() } @Test - fun getDependencySubstitutions_withDefaultGroup_substitutesCorrectly() { + fun configureDependencies_withVersionStringAndGroupString_appliesOnAllProjects_withHermesV1() { + val rootProject = ProjectBuilder.builder().build() + val appProject = ProjectBuilder.builder().withName("app").withParent(rootProject).build() + val libProject = ProjectBuilder.builder().withName("lib").withParent(rootProject).build() + appProject.plugins.apply("com.android.application") + libProject.plugins.apply("com.android.library") + + configureDependencies( + appProject, + DependencyUtils.Coordinates( + "1.2.3", + "4.5.6", + "7.8.9", + "io.github.test", + "io.github.test.hermes", + ), + hermesV1Enabled = true, + ) + + val appForcedModules = appProject.configurations.first().resolutionStrategy.forcedModules + val libForcedModules = libProject.configurations.first().resolutionStrategy.forcedModules + assertThat(appForcedModules.any { it.toString() == "io.github.test:react-android:1.2.3" }) + .isTrue() + assertThat( + appForcedModules.any { it.toString() == "io.github.test.hermes:hermes-android:7.8.9" } + ) + .isTrue() + assertThat(libForcedModules.any { it.toString() == "io.github.test:react-android:1.2.3" }) + .isTrue() + assertThat( + libForcedModules.any { it.toString() == "io.github.test.hermes:hermes-android:7.8.9" } + ) + .isTrue() + } + + @Test + fun getDependencySubstitutions_withDefaultGroup_substitutesCorrectly_withClassicHermes() { val dependencySubstitutions = - getDependencySubstitutions(DependencyUtils.Coordinates("0.42.0", "0.42.0")) + getDependencySubstitutions(DependencyUtils.Coordinates("0.42.0", "0.42.0", "0.43.0")) assertThat("com.facebook.react:react-native").isEqualTo(dependencySubstitutions[0].first) assertThat("com.facebook.react:react-android:0.42.0") @@ -364,10 +447,40 @@ class DependencyUtilsTest { } @Test - fun getDependencySubstitutions_withCustomGroup_substitutesCorrectly() { + fun getDependencySubstitutions_withDefaultGroup_substitutesCorrectly_withHermesV1() { val dependencySubstitutions = getDependencySubstitutions( - DependencyUtils.Coordinates("0.42.0", "0.42.0", "io.github.test") + DependencyUtils.Coordinates("0.42.0", "0.42.0", "0.43.0"), + hermesV1Enabled = true, + ) + + assertThat("com.facebook.react:react-native").isEqualTo(dependencySubstitutions[0].first) + assertThat("com.facebook.react:react-android:0.42.0") + .isEqualTo(dependencySubstitutions[0].second) + assertThat( + "The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210." + ) + .isEqualTo(dependencySubstitutions[0].third) + assertThat("com.facebook.react:hermes-engine").isEqualTo(dependencySubstitutions[1].first) + assertThat("com.facebook.hermes:hermes-android:0.43.0") + .isEqualTo(dependencySubstitutions[1].second) + assertThat( + "The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210." + ) + .isEqualTo(dependencySubstitutions[1].third) + } + + @Test + fun getDependencySubstitutions_withCustomGroup_substitutesCorrectly_withClassicHermes() { + val dependencySubstitutions = + getDependencySubstitutions( + DependencyUtils.Coordinates( + "0.42.0", + "0.42.0", + "0.43.0", + "io.github.test", + "io.github.test.hermes", + ) ) assertThat("com.facebook.react:react-native").isEqualTo(dependencySubstitutions[0].first) @@ -392,6 +505,44 @@ class DependencyUtilsTest { .isEqualTo(dependencySubstitutions[3].third) } + @Test + fun getDependencySubstitutions_withCustomGroup_substitutesCorrectly_withHermesV1() { + val dependencySubstitutions = + getDependencySubstitutions( + DependencyUtils.Coordinates( + "0.42.0", + "0.42.0", + "0.43.0", + "io.github.test", + "io.github.test.hermes", + ), + hermesV1Enabled = true, + ) + + assertThat("com.facebook.react:react-native").isEqualTo(dependencySubstitutions[0].first) + assertThat("io.github.test:react-android:0.42.0").isEqualTo(dependencySubstitutions[0].second) + assertThat( + "The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210." + ) + .isEqualTo(dependencySubstitutions[0].third) + assertThat("com.facebook.react:hermes-engine").isEqualTo(dependencySubstitutions[1].first) + assertThat("io.github.test.hermes:hermes-android:0.43.0") + .isEqualTo(dependencySubstitutions[1].second) + assertThat( + "The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210." + ) + .isEqualTo(dependencySubstitutions[1].third) + assertThat("com.facebook.react:react-android").isEqualTo(dependencySubstitutions[2].first) + assertThat("io.github.test:react-android:0.42.0").isEqualTo(dependencySubstitutions[2].second) + assertThat("The react-android dependency was modified to use the correct Maven group.") + .isEqualTo(dependencySubstitutions[2].third) + assertThat("com.facebook.react:hermes-android").isEqualTo(dependencySubstitutions[3].first) + assertThat("io.github.test.hermes:hermes-android:0.43.0") + .isEqualTo(dependencySubstitutions[3].second) + assertThat("The hermes-android dependency was modified to use the correct Maven group.") + .isEqualTo(dependencySubstitutions[3].third) + } + @Test fun readVersionString_withCorrectVersionString_returnsIt() { val propertiesFile = @@ -405,9 +556,25 @@ class DependencyUtilsTest { ) } - val versionString = readVersionAndGroupStrings(propertiesFile).versionString + val hermesVersionFile = + tempFolder.newFile("version.properties").apply { + writeText( + """ + HERMES_V1_VERSION_NAME=1000.0.0 + ANOTHER_PROPERTY=true + """ + .trimIndent() + ) + } + + val strings = readVersionAndGroupStrings(propertiesFile, hermesVersionFile) + val versionString = strings.versionString + val hermesVersionString = strings.hermesVersionString + val hermesV1VersionString = strings.hermesV1VersionString assertThat(versionString).isEqualTo("1000.0.0") + assertThat(hermesVersionString).isEqualTo("1000.0.0") + assertThat(hermesV1VersionString).isEqualTo("1000.0.0") } @Test @@ -417,15 +584,33 @@ class DependencyUtilsTest { writeText( """ VERSION_NAME=0.0.0-20221101-2019-cfe811ab1 + HERMES_VERSION_NAME=0.12.0-commitly-20221101-2019-cfe811ab1 + HERMES_V1_VERSION_NAME=250829098.0.0-stable + ANOTHER_PROPERTY=true + """ + .trimIndent() + ) + } + + val hermesVersionFile = + tempFolder.newFile("version.properties").apply { + writeText( + """ + HERMES_V1_VERSION_NAME=250829098.0.0-stable ANOTHER_PROPERTY=true """ .trimIndent() ) } - val versionString = readVersionAndGroupStrings(propertiesFile).versionString + val strings = readVersionAndGroupStrings(propertiesFile, hermesVersionFile) + val versionString = strings.versionString + val hermesVersionString = strings.hermesVersionString + val hermesV1VersionString = strings.hermesV1VersionString assertThat(versionString).isEqualTo("0.0.0-20221101-2019-cfe811ab1-SNAPSHOT") + assertThat(hermesVersionString).isEqualTo("0.0.0-20221101-2019-cfe811ab1-SNAPSHOT") + assertThat(hermesV1VersionString).isEqualTo("250829098.0.0-stable") } @Test @@ -440,8 +625,23 @@ class DependencyUtilsTest { ) } - val versionString = readVersionAndGroupStrings(propertiesFile).versionString + val hermesVersionFile = + tempFolder.newFile("version.properties").apply { + writeText( + """ + ANOTHER_PROPERTY=true + """ + .trimIndent() + ) + } + + val strings = readVersionAndGroupStrings(propertiesFile, hermesVersionFile) + val versionString = strings.versionString + val hermesVersionString = strings.hermesVersionString + val hermesV1VersionString = strings.hermesV1VersionString assertThat(versionString).isEqualTo("") + assertThat(hermesVersionString).isEqualTo("") + assertThat(hermesV1VersionString).isEqualTo("") } @Test @@ -457,8 +657,24 @@ class DependencyUtilsTest { ) } - val versionString = readVersionAndGroupStrings(propertiesFile).versionString + val hermesVersionFile = + tempFolder.newFile("version.properties").apply { + writeText( + """ + HERMES_V1_VERSION_NAME= + ANOTHER_PROPERTY=true + """ + .trimIndent() + ) + } + + val strings = readVersionAndGroupStrings(propertiesFile, hermesVersionFile) + val versionString = strings.versionString + val hermesVersionString = strings.hermesVersionString + val hermesV1VersionString = strings.hermesV1VersionString assertThat(versionString).isEqualTo("") + assertThat(hermesVersionString).isEqualTo("") + assertThat(hermesV1VersionString).isEqualTo("") } @Test @@ -468,15 +684,30 @@ class DependencyUtilsTest { writeText( """ react.internal.publishingGroup=io.github.test + react.internal.hermesPublishingGroup=io.github.test ANOTHER_PROPERTY=true """ .trimIndent() ) } - val groupString = readVersionAndGroupStrings(propertiesFile).reactGroupString + val hermesVersionFile = + tempFolder.newFile("version.properties").apply { + writeText( + """ + HERMES_V1_VERSION_NAME= + ANOTHER_PROPERTY=true + """ + .trimIndent() + ) + } - assertThat(groupString).isEqualTo("io.github.test") + val strings = readVersionAndGroupStrings(propertiesFile, hermesVersionFile) + val reactGroupString = strings.reactGroupString + val hermesGroupString = strings.hermesGroupString + + assertThat(reactGroupString).isEqualTo("io.github.test") + assertThat(hermesGroupString).isEqualTo("io.github.test") } @Test @@ -491,9 +722,23 @@ class DependencyUtilsTest { ) } - val groupString = readVersionAndGroupStrings(propertiesFile).reactGroupString + val hermesVersionFile = + tempFolder.newFile("version.properties").apply { + writeText( + """ + HERMES_V1_VERSION_NAME= + ANOTHER_PROPERTY=true + """ + .trimIndent() + ) + } + + val strings = readVersionAndGroupStrings(propertiesFile, hermesVersionFile) + val reactGroupString = strings.reactGroupString + val hermesGroupString = strings.hermesGroupString - assertThat(groupString).isEqualTo("com.facebook.react") + assertThat(reactGroupString).isEqualTo("com.facebook.react") + assertThat(hermesGroupString).isEqualTo("com.facebook.hermes") } @Test diff --git a/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/PathUtilsTest.kt b/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/PathUtilsTest.kt index 4a12ed750f89..c655fd5b77cf 100644 --- a/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/PathUtilsTest.kt +++ b/packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/PathUtilsTest.kt @@ -166,7 +166,7 @@ class PathUtilsTest { @WithOs(OS.MAC) fun detectOSAwareHermesCommand_withHermesV1Enabled() { tempFolder.newFolder("node_modules/hermes-compiler/osx-bin/") - val expected = tempFolder.newFile("node_modules/hermes-compiler/osx-bin//hermesc") + val expected = tempFolder.newFile("node_modules/hermes-compiler/osx-bin/hermesc") assertThat(detectOSAwareHermesCommand(tempFolder.root, "", hermesV1Enabled = true)) .isEqualTo(expected.toString()) diff --git a/packages/react-native/ReactAndroid/gradle.properties b/packages/react-native/ReactAndroid/gradle.properties index 85e0a3518de1..825e7245b116 100644 --- a/packages/react-native/ReactAndroid/gradle.properties +++ b/packages/react-native/ReactAndroid/gradle.properties @@ -1,5 +1,4 @@ VERSION_NAME=0.82.0-rc.1 -HERMES_VERSION_NAME=1000.0.0 react.internal.publishingGroup=com.facebook.react react.internal.hermesPublishingGroup=com.facebook.hermes diff --git a/packages/react-native/sdks/hermes-engine/hermes-engine.podspec b/packages/react-native/sdks/hermes-engine/hermes-engine.podspec index f772282f9a3d..95d10f3a9bbb 100644 --- a/packages/react-native/sdks/hermes-engine/hermes-engine.podspec +++ b/packages/react-native/sdks/hermes-engine/hermes-engine.podspec @@ -20,9 +20,14 @@ end # package.json package = JSON.parse(File.read(File.join(react_native_path, "package.json"))) -# TODO: T231755000 use the Hermes V1 version instead of React Native version +# TODO: T231755000 read hermes version from version.properties when consuming hermes version = package['version'] +if ENV['RCT_HERMES_V1_ENABLED'] == "1" + versionProperties = Hash[*File.read("version.properties").split(/[=\n]+/)] + version = versionProperties['HERMES_V1_VERSION_NAME'] +end + source_type = hermes_source_type(version, react_native_path) source = podspec_source(source_type, version, react_native_path) diff --git a/packages/react-native/sdks/hermes-engine/version.properties b/packages/react-native/sdks/hermes-engine/version.properties new file mode 100644 index 000000000000..2ba9ab3b471c --- /dev/null +++ b/packages/react-native/sdks/hermes-engine/version.properties @@ -0,0 +1 @@ +HERMES_V1_VERSION_NAME=250829098.0.0