Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/actions/build-android/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,19 @@ runs:
if [[ "${{ inputs.release-type }}" == "dry-run" ]]; then
# dry-run: we only build ARM64 to save time/resources. For release/nightlies the default is to build all archs.
export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a,x86" # x86 is required for E2E testing
export HERMES_PREBUILT_FLAG="ORG_GRADLE_PROJECT_react.internal.useHermesNightly=true"
TASKS="publishAllToMavenTempLocal build"
elif [[ "${{ inputs.release-type }}" == "nightly" ]]; then
# nightly: we set isSnapshot to true so artifacts are sent to the right repository on Maven Central.
export ORG_GRADLE_PROJECT_isSnapshot="true"
export HERMES_PREBUILT_FLAG="ORG_GRADLE_PROJECT_react.internal.useHermesNightly=true"
TASKS="publishAllToMavenTempLocal publishAndroidToSonatype build"
else
# release: we want to build all archs (default)
export HERMES_PREBUILT_FLAG="ORG_GRADLE_PROJECT_react.internal.useHermesStable=true"
TASKS="publishAllToMavenTempLocal publishAndroidToSonatype build"
fi
./gradlew $TASKS -PenableWarningsAsErrors=true
env "$HERMES_PREBUILT_FLAG" ./gradlew $TASKS -PenableWarningsAsErrors=true
- name: Save Android ccache
if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }}
uses: actions/cache/save@v5
Expand Down
47 changes: 41 additions & 6 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,43 @@ tasks.register("publishAllToMavenTempLocal") {
tasks.register("publishAndroidToSonatype") {
description = "Publish the Android artifacts to Sonatype (Maven Central or Snapshot repository)"
dependsOn(":packages:react-native:ReactAndroid:publishToSonatype")
dependsOn(":packages:react-native:ReactAndroid:hermes-engine:publishToSonatype")
}

if (project.findProperty("react.internal.useHermesNightly")?.toString()?.toBoolean() == true) {
var hermesSubstitution: Pair<String, String>? = null

if (project.findProperty("react.internal.useHermesStable")?.toString()?.toBoolean() == true) {
val hermesVersions = java.util.Properties()
val hermesVersionPropertiesFile =
File("./packages/react-native/sdks/hermes-engine/version.properties")
hermesVersionPropertiesFile.inputStream().use { hermesVersions.load(it) }
val selectedHermesVersion = hermesVersions["HERMES_VERSION_NAME"] as String

hermesSubstitution = selectedHermesVersion to "Users opted to use stable hermes release"
} else if (
project.findProperty("react.internal.useHermesNightly")?.toString()?.toBoolean() == true
) {
val reactNativePackageJson = File("./packages/react-native/package.json")
val reactNativePackageJsonContent = reactNativePackageJson.readText()
val packageJson = groovy.json.JsonSlurper().parseText(reactNativePackageJsonContent) as Map<*, *>

val hermesCompilerVersion =
(packageJson["dependencies"] as Map<*, *>)["hermes-compiler"] as String

if (hermesCompilerVersion == "0.0.0") {
throw RuntimeException(
"Trying to use Hermes Nightly but hermes-compiler version is not specified"
)
}

hermesSubstitution = "$hermesCompilerVersion-SNAPSHOT" to "Users opted to use hermes nightly"
} else {
logger.warn(
"""
********************************************************************************
INFO: You're using Hermes from nightly as you set
INFO: You're building Hermes from source as you set

react.internal.useHermesNightly=true
react.internal.useHermesStable=false
react.internal.useHermesNightly=false

in the ./gradle.properties file.

Expand All @@ -127,12 +154,20 @@ if (project.findProperty("react.internal.useHermesNightly")?.toString()?.toBoole
"""
.trimIndent()
)
}

if (hermesSubstitution != null) {
val (hermesVersion, reason) = hermesSubstitution!!
project(":packages:react-native:ReactAndroid:hermes-engine") {
tasks.configureEach { enabled = false }
}

allprojects {
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute(project(":packages:react-native:ReactAndroid:hermes-engine"))
.using(module("com.facebook.hermes:hermes-android:0.+"))
.because("Users opted to use hermes from nightly")
.using(module("com.facebook.hermes:hermes-android:$hermesVersion"))
.because(reason)
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@ android.newDsl=false
# ./gradlew <task> -PreactNativeArchitectures=x86_64
reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64

# Controls whether to use Hermes from stable builds. This will force hermes version
# set in the sdks/hermes-engine/version.properties file to be used. This has a higher
# priority than react.internal.useHermesNightly.
react.internal.useHermesStable=false

# Controls whether to use Hermes from nightly builds. This will speed up builds
# but should NOT be turned on for CI or release builds.
react.internal.useHermesNightly=false
react.internal.useHermesNightly=true

# Controls whether to use Hermes 1.0. Clean and rebuild when changing.
hermesV1Enabled=false
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"lint-kotlin": "./gradlew ktfmtFormat",
"lint-markdown": "markdownlint-cli2 2>&1",
"lint": "eslint --max-warnings 0 .",
"preinstall": "node ./scripts/try-set-nightly-hermes-compiler.js",
"prettier": "prettier --write \"./**/*.{js,md,yml,ts,tsx}\"",
"print-packages": "node ./scripts/monorepo/print",
"shellcheck": "./.github/workflow-scripts/analyze_scripts.sh",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ object PropertyUtils {
*/
const val INTERNAL_REACT_WINDOWS_BASH = "react.internal.windowsBashPath"

/**
* Controls whether to use Hermes from stable builds. This will force hermes version set in the
* sdks/hermes-engine/version.properties file to be used. This has a higher priority than
* react.internal.useHermesNightly.
*/
const val INTERNAL_USE_HERMES_STABLE = "react.internal.useHermesStable"

/**
* Internal property to force the build to use Hermes from the latest nightly. This speeds up the
* build at the cost of not testing the latest integration against Hermes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import de.undercouch.gradle.tasks.download.Download
import org.apache.tools.ant.taskdefs.condition.Os

plugins {
id("maven-publish")
id("signing")
alias(libs.plugins.android.library)
alias(libs.plugins.download)
Expand Down Expand Up @@ -348,10 +347,7 @@ android {
java.srcDirs("$hermesDir/lib/Platform/Intl/java", "$hermesDir/lib/Platform/Unicode/java")
}

buildFeatures {
prefab = true
prefabPublishing = true
}
buildFeatures { prefab = true }

dependencies {
implementation(libs.fbjni)
Expand All @@ -365,13 +361,6 @@ android {
jniLibs.excludes.add("**/libfbjni.so")
}

publishing {
multipleVariants {
withSourcesJar()
allVariants()
}
}

prefab { create("hermesvm") { headers = prefabHeadersDir.absolutePath } }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ else
version = versionProperties['HERMES_VERSION_NAME']
end

# Local monorepo build
if package['version'] == "1000.0.0" then
hermesCompilerVersion = package['dependencies']['hermes-compiler']
if hermesCompilerVersion != "0.0.0" then
version = hermesCompilerVersion
end
end

source_type = hermes_source_type(version, react_native_path)
source = podspec_source(source_type, version, react_native_path)

Expand Down
15 changes: 12 additions & 3 deletions packages/rn-tester/android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,14 @@ react {

/* Hermes Commands */
// The hermes compiler command to run. By default it is 'hermesc'
hermesCommand = "$reactNativeDirPath/ReactAndroid/hermes-engine/build/hermes/bin/hermesc"
hermesCommand =
if (
project.findProperty("react.internal.useHermesStable")?.toString()?.toBoolean() == true ||
project.findProperty("react.internal.useHermesNightly")?.toString()?.toBoolean() ==
true
)
"$rootDir/node_modules/hermes-compiler/hermesc/%OS-BIN%/hermesc"
else "$reactNativeDirPath/ReactAndroid/hermes-engine/build/hermes/bin/hermesc"

autolinkLibrariesWithApp()
}
Expand Down Expand Up @@ -179,8 +186,10 @@ tasks.withType<KotlinCompile>().configureEach {

afterEvaluate {
if (
project.findProperty("react.internal.useHermesNightly") == null ||
project.findProperty("react.internal.useHermesNightly").toString() == "false"
(project.findProperty("react.internal.useHermesNightly") == null ||
project.findProperty("react.internal.useHermesNightly").toString() == "false") &&
(project.findProperty("react.internal.useHermesStable") == null ||
project.findProperty("react.internal.useHermesStable").toString() == "false")
) {
// As we're consuming Hermes from source, we want to make sure
// `hermesc` is built before we actually invoke the `emit*HermesResource` task
Expand Down
8 changes: 8 additions & 0 deletions private/react-native-fantom/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,17 @@ val prepareRNCodegen by
into(codegenOutDir)
}

val enableHermesBuild by
tasks.registering {
project(":packages:react-native:ReactAndroid:hermes-engine") {
tasks.configureEach { enabled = true }
}
}

val prepareHermesDependencies by
tasks.registering {
dependsOn(
enableHermesBuild,
":packages:react-native:ReactAndroid:hermes-engine:buildHermesLib",
":packages:react-native:ReactAndroid:hermes-engine:prepareHeadersForPrefab",
)
Expand Down
26 changes: 26 additions & 0 deletions scripts/try-set-nightly-hermes-compiler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

// @flow
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');

function main() {
const packageJsonPath = path.join(__dirname, '../packages/react-native/package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
const hermesCompilerVersion = packageJson.dependencies['hermes-compiler'];

if (hermesCompilerVersion === '0.0.0') {
console.log(`Hermes compiler version not set. Updating to the latest nightly release.`);
execSync('yarn workspace react-native add hermes-compiler@nightly --exact', { stdio: 'inherit' });
} else {
console.log(`Hermes compiler version set to ${hermesCompilerVersion}. Not setting nightly hermes.`);
}
}

main();
Loading