From 854f0b749e4f2e91dac46e01aa48509a2784c2c6 Mon Sep 17 00:00:00 2001 From: Dawid Malecki Date: Wed, 24 Jun 2026 12:06:03 +0200 Subject: [PATCH 1/7] integrate proxy server --- .../facebook/react/utils/DependencyUtils.kt | 9 ++++ .../react/utils/DependencyUtilsTest.kt | 51 +++++++++++++++++++ packages/react-native/package.json | 2 +- .../react-native/scripts/cocoapods/rncore.rb | 32 ++++++++---- .../scripts/cocoapods/rndependencies.rb | 30 +++++++---- .../scripts/ios-prebuild/hermes.js | 48 +++++++++++++---- .../ios-prebuild/reactNativeDependencies.js | 45 ++++++++++++---- .../sdks/hermes-engine/hermes-utils.rb | 28 +++++++--- 8 files changed, 198 insertions(+), 47 deletions(-) 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 b686aefa0162..4ee5651cf612 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 @@ -27,6 +27,7 @@ import org.gradle.api.Project import org.gradle.api.artifacts.repositories.MavenArtifactRepository internal object DependencyUtils { + private const val REACT_NATIVE_MAVEN_CACHE_URL = "https://rnmaven.swmtest.xyz/" internal data class Coordinates( val versionString: String, @@ -75,6 +76,14 @@ internal object DependencyUtils { repo.content { it.excludeGroup("org.webkit") } } } + if (!hasProperty(INTERNAL_REACT_NATIVE_MAVEN_LOCAL_REPO)) { + mavenRepoFromUrl(REACT_NATIVE_MAVEN_CACHE_URL) { repo -> + repo.content { + it.includeGroupByRegex("com\\.facebook\\.react.*") + it.includeGroupByRegex("com\\.facebook\\.hermes.*") + } + } + } repositories.mavenCentral { repo -> // We don't want to fetch JSC from Maven Central as there are older versions there. repo.content { it.excludeGroup("org.webkit") } 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 5c57bb296fa4..7726c9a0f265 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 @@ -61,6 +61,21 @@ class DependencyUtilsTest { .isNotNull() } + @Test + fun configureRepositories_containsReactNativeMavenCache() { + val repositoryURI = URI.create("https://rnmaven.swmtest.xyz/") + val project = createProject() + + configureRepositories(project, false) + + assertThat( + project.repositories.firstOrNull { + it is MavenArtifactRepository && it.url == repositoryURI + } + ) + .isNotNull() + } + @Test fun configureRepositories_containsGoogleRepo() { val repositoryURI = URI.create("https://dl.google.com/dl/android/maven2/") @@ -221,6 +236,42 @@ class DependencyUtilsTest { assertThat(indexOfLocalRepo < indexOfMavenCentral).isTrue() } + @Test + fun configureRepositories_mavenCacheHasHigherPriorityThanMavenCentral() { + val mavenCacheURI = URI.create("https://rnmaven.swmtest.xyz/") + val mavenCentralURI = URI.create("https://repo.maven.apache.org/maven2/") + val project = createProject() + + configureRepositories(project, false) + + val indexOfMavenCache = + project.repositories.indexOfFirst { + it is MavenArtifactRepository && it.url == mavenCacheURI + } + val indexOfMavenCentral = + project.repositories.indexOfFirst { + it is MavenArtifactRepository && it.url == mavenCentralURI + } + assertThat(indexOfMavenCache < indexOfMavenCentral).isTrue() + } + + @Test + fun configureRepositories_withProjectPropertySet_doesNotContainMavenCache() { + val localMaven = tempFolder.newFolder("m2") + val mavenCacheURI = URI.create("https://rnmaven.swmtest.xyz/") + val project = createProject() + project.extensions.extraProperties.set("react.internal.mavenLocalRepo", localMaven.absolutePath) + + configureRepositories(project, false) + + assertThat( + project.repositories.firstOrNull { + it is MavenArtifactRepository && it.url == mavenCacheURI + } + ) + .isNull() + } + @Test fun configureRepositories_snapshotRepoHasHigherPriorityThanMavenCentral() { val repositoryURI = URI.create("https://central.sonatype.com/repository/maven-snapshots/") diff --git a/packages/react-native/package.json b/packages/react-native/package.json index ec26182439fe..ddf4b98c998a 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -167,7 +167,7 @@ "base64-js": "^1.5.1", "commander": "^12.0.0", "flow-enums-runtime": "^0.0.6", - "hermes-compiler": "0.0.0", + "hermes-compiler": "250829098.0.14", "invariant": "^2.2.4", "memoize-one": "^5.0.0", "metro-runtime": "^0.84.3", diff --git a/packages/react-native/scripts/cocoapods/rncore.rb b/packages/react-native/scripts/cocoapods/rncore.rb index 252588c98432..972e83ab7d73 100644 --- a/packages/react-native/scripts/cocoapods/rncore.rb +++ b/packages/react-native/scripts/cocoapods/rncore.rb @@ -44,6 +44,9 @@ def add_rncore_dependency(s) ## - RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS: If set to 1, it will download the dSYMs for the prebuilt RNCore frameworks and install these in the framework folders class ReactNativeCoreUtils + MAVEN_CENTRAL_REPOSITORY = "https://repo1.maven.org/maven2" + REACT_NATIVE_MAVEN_CACHE_REPOSITORY = "https://rnmaven.swmtest.xyz" + @@build_from_source = true @@react_native_path = "" @@react_native_version = "" @@ -364,16 +367,27 @@ def self.generate_plist_content(mappings) end def self.stable_tarball_url(version, build_type, dsyms = false) - ## You can use the `ENTERPRISE_REPOSITORY` ariable to customise the base url from which artifacts will be downloaded. - ## The mirror's structure must be the same of the Maven repo the react-native core team publishes on Maven Central. - maven_repo_url = - ENV['ENTERPRISE_REPOSITORY'] != nil && ENV['ENTERPRISE_REPOSITORY'] != "" ? - ENV['ENTERPRISE_REPOSITORY'] : - "https://repo1.maven.org/maven2" + candidates = stable_tarball_urls(version, build_type, dsyms) + return candidates.find { |url| artifact_exists(url) } || candidates.first + end + + def self.stable_tarball_urls(version, build_type, dsyms = false) group = "com/facebook/react" - # Sample url from Maven: - # https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.0/react-native-artifacts-0.81.0-reactnative-core-debug.tar.gz - return "#{maven_repo_url}/#{group}/react-native-artifacts/#{version}/react-native-artifacts-#{version}-reactnative-core-#{dsyms ? "dSYM-" : ""}#{build_type.to_s}.tar.gz" + return maven_repository_urls().map { |maven_repo_url| + # Sample url from Maven: + # https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.0/react-native-artifacts-0.81.0-reactnative-core-debug.tar.gz + "#{maven_repo_url}/#{group}/react-native-artifacts/#{version}/react-native-artifacts-#{version}-reactnative-core-#{dsyms ? "dSYM-" : ""}#{build_type.to_s}.tar.gz" + } + end + + def self.maven_repository_urls() + ## You can use the `ENTERPRISE_REPOSITORY` variable to customise the base url from which artifacts will be downloaded. + ## The mirror's structure must be the same of the Maven repo the react-native core team publishes on Maven Central. + if ENV['ENTERPRISE_REPOSITORY'] != nil && ENV['ENTERPRISE_REPOSITORY'] != "" + return [ENV['ENTERPRISE_REPOSITORY'].delete_suffix("/")] + end + + return [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY] end def self.nightly_tarball_url(version, configuration, dsyms = false) diff --git a/packages/react-native/scripts/cocoapods/rndependencies.rb b/packages/react-native/scripts/cocoapods/rndependencies.rb index 1c7fac1a6cb7..5cb4cae75000 100644 --- a/packages/react-native/scripts/cocoapods/rndependencies.rb +++ b/packages/react-native/scripts/cocoapods/rndependencies.rb @@ -57,6 +57,9 @@ def add_rn_third_party_dependencies(s) end class ReactNativeDependenciesUtils + MAVEN_CENTRAL_REPOSITORY = "https://repo1.maven.org/maven2" + REACT_NATIVE_MAVEN_CACHE_REPOSITORY = "https://rnmaven.swmtest.xyz" + @@build_from_source = true @@react_native_path = "" @@react_native_version = "" @@ -165,16 +168,25 @@ def self.podspec_source_download_prebuild_release_tarball() end def self.release_tarball_url(version, build_type) - ## You can use the `ENTERPRISE_REPOSITORY` ariable to customise the base url from which artifacts will be downloaded. - ## The mirror's structure must be the same of the Maven repo the react-native core team publishes on Maven Central. - maven_repo_url = - ENV['ENTERPRISE_REPOSITORY'] != nil && ENV['ENTERPRISE_REPOSITORY'] != "" ? - ENV['ENTERPRISE_REPOSITORY'] : - "https://repo1.maven.org/maven2" + candidates = release_tarball_urls(version, build_type) + return candidates.find { |url| artifact_exists(url) } || candidates.first + end + + def self.release_tarball_urls(version, build_type) group = "com/facebook/react" - # Sample url from Maven: - # https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.79.0-rc.0/react-native-artifacts-0.79.0-rc.0-reactnative-dependencies-debug.tar.gz - return "#{maven_repo_url}/#{group}/react-native-artifacts/#{version}/react-native-artifacts-#{version}-reactnative-dependencies-#{build_type.to_s}.tar.gz" + return maven_repository_urls().map { |maven_repo_url| + "#{maven_repo_url}/#{group}/react-native-artifacts/#{version}/react-native-artifacts-#{version}-reactnative-dependencies-#{build_type.to_s}.tar.gz" + } + end + + def self.maven_repository_urls() + ## You can use the `ENTERPRISE_REPOSITORY` variable to customise the base url from which artifacts will be downloaded. + ## The mirror's structure must be the same of the Maven repo the react-native core team publishes on Maven Central. + if ENV['ENTERPRISE_REPOSITORY'] != nil && ENV['ENTERPRISE_REPOSITORY'] != "" + return [ENV['ENTERPRISE_REPOSITORY'].delete_suffix("/")] + end + + return [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY] end def self.nightly_tarball_url(version, build_type) diff --git a/packages/react-native/scripts/ios-prebuild/hermes.js b/packages/react-native/scripts/ios-prebuild/hermes.js index eb3df6314352..a7c57049cb0b 100644 --- a/packages/react-native/scripts/ios-prebuild/hermes.js +++ b/packages/react-native/scripts/ios-prebuild/hermes.js @@ -17,6 +17,8 @@ const {promisify} = require('util'); const pipeline = promisify(stream.pipeline); const hermesLog = createLogger('Hermes'); +const MAVEN_CENTRAL_REPOSITORY = 'https://repo1.maven.org/maven2'; +const REACT_NATIVE_MAVEN_CACHE_REPOSITORY = 'https://rnmaven.swmtest.xyz'; /*:: import type {BuildFlavor, Destination, Platform} from './types'; @@ -187,16 +189,42 @@ function hermesEngineTarballEnvvarDefined() /*: boolean */ { return !!process.env.HERMES_ENGINE_TARBALL_PATH; } -function getTarballUrl( +async function getTarballUrl( version /*: string */, buildType /*: BuildFlavor */, -) /*: string */ { - // You can use the `ENTERPRISE_REPOSITORY` ariable to customise the base url from which artifacts will be downloaded. - // The mirror's structure must be the same of the Maven repo the react-native core team publishes on Maven Central. - const mavenRepoUrl = - process.env.ENTERPRISE_REPOSITORY ?? 'https://repo1.maven.org/maven2'; +) /*: Promise */ { + const candidates = getTarballUrls(version, buildType); + for (const url of candidates) { + console.log(`Checking if Hermes artifact exists at URL: ${url}`); + if (await hermesArtifactExists(url)) { + console.log(`Found Hermes artifact at URL: ${url}`); + return url; + } + console.log(`Hermes artifact not found at URL: ${url}`); + } + return candidates[0]; +} + +function getTarballUrls( + version /*: string */, + buildType /*: BuildFlavor */, +) /*: Array */ { const namespace = 'com/facebook/hermes'; - return `${mavenRepoUrl}/${namespace}/hermes-ios/${version}/hermes-ios-${version}-hermes-ios-${buildType.toLowerCase()}.tar.gz`; + return getMavenRepositoryUrls().map( + mavenRepoUrl => + `${mavenRepoUrl}/${namespace}/hermes-ios/${version}/hermes-ios-${version}-hermes-ios-${buildType.toLowerCase()}.tar.gz`, + ); +} + +function getMavenRepositoryUrls() /*: Array */ { + // You can use the `ENTERPRISE_REPOSITORY` variable to customise the base url from which artifacts will be downloaded. + // The mirror's structure must be the same of the Maven repo the react-native core team publishes on Maven Central. + const enterpriseRepository = process.env.ENTERPRISE_REPOSITORY; + if (enterpriseRepository != null && enterpriseRepository !== '') { + return [enterpriseRepository.replace(/\/+$/, '')]; + } + + return [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY]; } /** @@ -228,7 +256,7 @@ async function hermesSourceType( return HermesEngineSourceTypes.LOCAL_PREBUILT_TARBALL; } - const tarballUrl = getTarballUrl(version, buildType); + const tarballUrl = await getTarballUrl(version, buildType); if (await hermesArtifactExists(tarballUrl)) { hermesLog(`Using download prebuild ${buildType} tarball`); return HermesEngineSourceTypes.DOWNLOAD_PREBUILD_TARBALL; @@ -278,7 +306,7 @@ async function downloadPrebuildTarball( buildType /*: BuildFlavor */, artifactsPath /*: string*/, ) /*: Promise */ { - const url = getTarballUrl(version, buildType); + const url = await getTarballUrl(version, buildType); hermesLog(`Using release tarball from URL: ${url}`); return downloadStableHermes(version, buildType, artifactsPath); } @@ -288,7 +316,7 @@ async function downloadStableHermes( buildType /*: BuildFlavor */, artifactsPath /*: string */, ) /*: Promise */ { - const tarballUrl = getTarballUrl(version, buildType); + const tarballUrl = await getTarballUrl(version, buildType); return downloadHermesTarball(tarballUrl, version, buildType, artifactsPath); } diff --git a/packages/react-native/scripts/ios-prebuild/reactNativeDependencies.js b/packages/react-native/scripts/ios-prebuild/reactNativeDependencies.js index f497338bef8b..ba436f99d1e8 100644 --- a/packages/react-native/scripts/ios-prebuild/reactNativeDependencies.js +++ b/packages/react-native/scripts/ios-prebuild/reactNativeDependencies.js @@ -20,6 +20,8 @@ const {promisify} = require('util'); const pipeline = promisify(stream.pipeline); const dependencyLog = createLogger('ReactNativeDependencies'); +const MAVEN_CENTRAL_REPOSITORY = 'https://repo1.maven.org/maven2'; +const REACT_NATIVE_MAVEN_CACHE_REPOSITORY = 'https://rnmaven.swmtest.xyz'; /** * Downloads ReactNativeDependencies artifacts from the specified version and build type. If you want to specify a specific @@ -178,16 +180,39 @@ function checkExistingVersion( return false; } -function getTarballUrl( +async function getTarballUrl( version /*: string */, buildType /*: BuildFlavor */, -) /*: string */ { - // You can use the `ENTERPRISE_REPOSITORY` ariable to customise the base url from which artifacts will be downloaded. - // The mirror's structure must be the same of the Maven repo the react-native core team publishes on Maven Central. - const mavenRepoUrl = - process.env.ENTERPRISE_REPOSITORY ?? 'https://repo1.maven.org/maven2'; +) /*: Promise */ { + const candidates = getTarballUrls(version, buildType); + for (const url of candidates) { + if (await reactNativeDependenciesArtifactExists(url)) { + return url; + } + } + return candidates[0]; +} + +function getTarballUrls( + version /*: string */, + buildType /*: BuildFlavor */, +) /*: Array */ { const namespace = 'com/facebook/react'; - return `${mavenRepoUrl}/${namespace}/react-native-artifacts/${version}/react-native-artifacts-${version}-reactnative-dependencies-${buildType.toLowerCase()}.tar.gz`; + return getMavenRepositoryUrls().map( + mavenRepoUrl => + `${mavenRepoUrl}/${namespace}/react-native-artifacts/${version}/react-native-artifacts-${version}-reactnative-dependencies-${buildType.toLowerCase()}.tar.gz`, + ); +} + +function getMavenRepositoryUrls() /*: Array */ { + // You can use the `ENTERPRISE_REPOSITORY` variable to customise the base url from which artifacts will be downloaded. + // The mirror's structure must be the same of the Maven repo the react-native core team publishes on Maven Central. + const enterpriseRepository = process.env.ENTERPRISE_REPOSITORY; + if (enterpriseRepository != null && enterpriseRepository !== '') { + return [enterpriseRepository.replace(/\/+$/, '')]; + } + + return [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY]; } async function getNightlyTarballUrl( @@ -230,7 +255,7 @@ async function reactNativeDependenciesSourceType( version /*: string */, buildType /*: BuildFlavor */, ) /*: Promise */ { - const tarballUrl = getTarballUrl(version, buildType); + const tarballUrl = await getTarballUrl(version, buildType); if (await reactNativeDependenciesArtifactExists(tarballUrl)) { dependencyLog(`Using download prebuild ${buildType} tarball`); return ReactNativeDependenciesEngineSourceTypes.DOWNLOAD_PREBUILD_TARBALL; @@ -273,7 +298,7 @@ async function downloadPrebuildTarball( buildType /*: BuildFlavor */, artifactsPath /*: string*/, ) /*: Promise */ { - const url = getTarballUrl(version, buildType); + const url = await getTarballUrl(version, buildType); dependencyLog(`Using release tarball from URL: ${url}`); return downloadStableReactNativeDependencies( version, @@ -302,7 +327,7 @@ async function downloadStableReactNativeDependencies( buildType /*: BuildFlavor */, artifactsPath /*: string */, ) /*: Promise */ { - const tarballUrl = getTarballUrl(version, buildType); + const tarballUrl = await getTarballUrl(version, buildType); return downloadReactNativeDependenciesTarball( tarballUrl, version, diff --git a/packages/react-native/sdks/hermes-engine/hermes-utils.rb b/packages/react-native/sdks/hermes-engine/hermes-utils.rb index 288a5b638543..80ae4001056d 100644 --- a/packages/react-native/sdks/hermes-engine/hermes-utils.rb +++ b/packages/react-native/sdks/hermes-engine/hermes-utils.rb @@ -7,6 +7,8 @@ HERMES_GITHUB_URL = "https://github.com/facebook/hermes.git" ENV_BUILD_FROM_SOURCE = "RCT_BUILD_HERMES_FROM_SOURCE" +MAVEN_CENTRAL_REPOSITORY = "https://repo1.maven.org/maven2" +REACT_NATIVE_MAVEN_CACHE_REPOSITORY = "https://rnmaven.swmtest.xyz" module HermesEngineSourceType LOCAL_PREBUILT_TARBALL = :local_prebuilt_tarball @@ -190,17 +192,27 @@ def hermestag_file(react_native_path) end def release_tarball_url(version, build_type) + candidates = release_tarball_urls(version, build_type) + return candidates.find { |url| hermes_artifact_exists(url) } || candidates.first +end + +def release_tarball_urls(version, build_type) + namespace = "com/facebook/hermes" + return maven_repository_urls().map { |maven_repo_url| + # Sample url from Maven: + # https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/0.14.0/hermes-ios-0.14.0-hermes-ios-debug.tar.gz + "#{maven_repo_url}/#{namespace}/hermes-ios/#{version}/hermes-ios-#{version}-hermes-ios-#{build_type.to_s}.tar.gz" + } +end + +def maven_repository_urls() ## You can use the `ENTERPRISE_REPOSITORY` variable to customise the base url from which artifacts will be downloaded. ## The mirror's structure must be the same of the Maven repo the react-native core team publishes on Maven Central. - maven_repo_url = - ENV['ENTERPRISE_REPOSITORY'] != nil && ENV['ENTERPRISE_REPOSITORY'] != "" ? - ENV['ENTERPRISE_REPOSITORY'] : - "https://repo1.maven.org/maven2" + if ENV['ENTERPRISE_REPOSITORY'] != nil && ENV['ENTERPRISE_REPOSITORY'] != "" + return [ENV['ENTERPRISE_REPOSITORY'].delete_suffix("/")] + end - namespace = "com/facebook/hermes" - # Sample url from Maven: - # https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/0.14.0/hermes-ios-0.14.0-hermes-ios-debug.tar.gz - return "#{maven_repo_url}/#{namespace}/hermes-ios/#{version}/hermes-ios-#{version}-hermes-ios-#{build_type.to_s}.tar.gz" + return [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY] end def download_stable_hermes(react_native_path, version, configuration) From e7d71749f4e4f25fe830648d6a215de30e5f1302 Mon Sep 17 00:00:00 2001 From: Dawid Malecki Date: Wed, 24 Jun 2026 12:26:46 +0200 Subject: [PATCH 2/7] reduce artifacts exists calls on iOS builds --- .../scripts/ios-prebuild/hermes.js | 30 ++++++++++++++----- .../ios-prebuild/reactNativeDependencies.js | 27 ++++++++++++++--- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/packages/react-native/scripts/ios-prebuild/hermes.js b/packages/react-native/scripts/ios-prebuild/hermes.js index a7c57049cb0b..b5b5df656324 100644 --- a/packages/react-native/scripts/ios-prebuild/hermes.js +++ b/packages/react-native/scripts/ios-prebuild/hermes.js @@ -19,6 +19,7 @@ const pipeline = promisify(stream.pipeline); const hermesLog = createLogger('Hermes'); const MAVEN_CENTRAL_REPOSITORY = 'https://repo1.maven.org/maven2'; const REACT_NATIVE_MAVEN_CACHE_REPOSITORY = 'https://rnmaven.swmtest.xyz'; +const artifactExistenceCache = new Map(); /*:: import type {BuildFlavor, Destination, Platform} from './types'; @@ -193,16 +194,25 @@ async function getTarballUrl( version /*: string */, buildType /*: BuildFlavor */, ) /*: Promise */ { + const existingUrl = await findExistingTarballUrl(version, buildType); + if (existingUrl != null) { + return existingUrl; + } + + return getTarballUrls(version, buildType)[0]; +} + +async function findExistingTarballUrl( + version /*: string */, + buildType /*: BuildFlavor */, +) /*: Promise */ { const candidates = getTarballUrls(version, buildType); for (const url of candidates) { - console.log(`Checking if Hermes artifact exists at URL: ${url}`); if (await hermesArtifactExists(url)) { - console.log(`Found Hermes artifact at URL: ${url}`); return url; } - console.log(`Hermes artifact not found at URL: ${url}`); } - return candidates[0]; + return null; } function getTarballUrls( @@ -233,13 +243,20 @@ function getMavenRepositoryUrls() /*: Array */ { async function hermesArtifactExists( tarballUrl /*: string */, ) /*: Promise */ { + if (artifactExistenceCache.has(tarballUrl)) { + return artifactExistenceCache.get(tarballUrl); + } + try { const response /*: Response */ = await fetch(tarballUrl, { method: 'HEAD', }); - return response.status === 200; + const exists = response.status === 200; + artifactExistenceCache.set(tarballUrl, exists); + return exists; } catch (e) { + artifactExistenceCache.set(tarballUrl, false); return false; } } @@ -256,8 +273,7 @@ async function hermesSourceType( return HermesEngineSourceTypes.LOCAL_PREBUILT_TARBALL; } - const tarballUrl = await getTarballUrl(version, buildType); - if (await hermesArtifactExists(tarballUrl)) { + if ((await findExistingTarballUrl(version, buildType)) != null) { hermesLog(`Using download prebuild ${buildType} tarball`); return HermesEngineSourceTypes.DOWNLOAD_PREBUILD_TARBALL; } diff --git a/packages/react-native/scripts/ios-prebuild/reactNativeDependencies.js b/packages/react-native/scripts/ios-prebuild/reactNativeDependencies.js index ba436f99d1e8..dcd6c02ae87a 100644 --- a/packages/react-native/scripts/ios-prebuild/reactNativeDependencies.js +++ b/packages/react-native/scripts/ios-prebuild/reactNativeDependencies.js @@ -22,6 +22,7 @@ const pipeline = promisify(stream.pipeline); const dependencyLog = createLogger('ReactNativeDependencies'); const MAVEN_CENTRAL_REPOSITORY = 'https://repo1.maven.org/maven2'; const REACT_NATIVE_MAVEN_CACHE_REPOSITORY = 'https://rnmaven.swmtest.xyz'; +const artifactExistenceCache = new Map(); /** * Downloads ReactNativeDependencies artifacts from the specified version and build type. If you want to specify a specific @@ -184,13 +185,25 @@ async function getTarballUrl( version /*: string */, buildType /*: BuildFlavor */, ) /*: Promise */ { + const existingUrl = await findExistingTarballUrl(version, buildType); + if (existingUrl != null) { + return existingUrl; + } + + return getTarballUrls(version, buildType)[0]; +} + +async function findExistingTarballUrl( + version /*: string */, + buildType /*: BuildFlavor */, +) /*: Promise */ { const candidates = getTarballUrls(version, buildType); for (const url of candidates) { if (await reactNativeDependenciesArtifactExists(url)) { return url; } } - return candidates[0]; + return null; } function getTarballUrls( @@ -237,13 +250,20 @@ async function getNightlyTarballUrl( async function reactNativeDependenciesArtifactExists( tarballUrl /*: string */, ) /*: Promise */ { + if (artifactExistenceCache.has(tarballUrl)) { + return artifactExistenceCache.get(tarballUrl); + } + try { const response /*: Response */ = await fetch(tarballUrl, { method: 'HEAD', }); - return response.status === 200; + const exists = response.status === 200; + artifactExistenceCache.set(tarballUrl, exists); + return exists; } catch (e) { + artifactExistenceCache.set(tarballUrl, false); return false; } } @@ -255,8 +275,7 @@ async function reactNativeDependenciesSourceType( version /*: string */, buildType /*: BuildFlavor */, ) /*: Promise */ { - const tarballUrl = await getTarballUrl(version, buildType); - if (await reactNativeDependenciesArtifactExists(tarballUrl)) { + if ((await findExistingTarballUrl(version, buildType)) != null) { dependencyLog(`Using download prebuild ${buildType} tarball`); return ReactNativeDependenciesEngineSourceTypes.DOWNLOAD_PREBUILD_TARBALL; } From fa2216495b3eb7f6cced4ee395e368ad7485167e Mon Sep 17 00:00:00 2001 From: Dawid Malecki Date: Wed, 24 Jun 2026 12:55:10 +0200 Subject: [PATCH 3/7] reduce artifacts exists calls in ruby --- packages/react-native/scripts/cocoapods/rncore.rb | 2 +- packages/react-native/scripts/cocoapods/rndependencies.rb | 2 +- packages/react-native/sdks/hermes-engine/hermes-utils.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-native/scripts/cocoapods/rncore.rb b/packages/react-native/scripts/cocoapods/rncore.rb index 972e83ab7d73..afa93dd05dea 100644 --- a/packages/react-native/scripts/cocoapods/rncore.rb +++ b/packages/react-native/scripts/cocoapods/rncore.rb @@ -489,7 +489,7 @@ def self.download_rncore_tarball(react_native_path, tarball_url, version, config end def self.release_artifact_exists(version) - return artifact_exists(stable_tarball_url(version, :debug)) + return stable_tarball_urls(version, :debug).any? { |url| artifact_exists(url) } end def self.nightly_artifact_exists(version) diff --git a/packages/react-native/scripts/cocoapods/rndependencies.rb b/packages/react-native/scripts/cocoapods/rndependencies.rb index 5cb4cae75000..9555f819658e 100644 --- a/packages/react-native/scripts/cocoapods/rndependencies.rb +++ b/packages/react-native/scripts/cocoapods/rndependencies.rb @@ -313,7 +313,7 @@ def self.download_rndeps_tarball(react_native_path, tarball_url, version, config end def self.release_artifact_exists(version) - return artifact_exists(release_tarball_url(version, :debug)) + return release_tarball_urls(version, :debug).any? { |url| artifact_exists(url) } end def self.nightly_artifact_exists(version) diff --git a/packages/react-native/sdks/hermes-engine/hermes-utils.rb b/packages/react-native/sdks/hermes-engine/hermes-utils.rb index 80ae4001056d..f05c98c59165 100644 --- a/packages/react-native/sdks/hermes-engine/hermes-utils.rb +++ b/packages/react-native/sdks/hermes-engine/hermes-utils.rb @@ -91,7 +91,7 @@ def force_build_from_stable_branch(react_native_path) end def release_artifact_exists(version) - return hermes_artifact_exists(release_tarball_url(version, :debug)) + return release_tarball_urls(version, :debug).any? { |url| hermes_artifact_exists(url) } end def podspec_source(source_type, version, react_native_path) From db9f786b281c8fbdafc8f40ab7d2a90fd675d43d Mon Sep 17 00:00:00 2001 From: Dawid Malecki Date: Wed, 24 Jun 2026 17:32:28 +0200 Subject: [PATCH 4/7] fix lint issues --- packages/react-native/scripts/ios-prebuild/hermes.js | 7 ++++--- .../scripts/ios-prebuild/reactNativeDependencies.js | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/react-native/scripts/ios-prebuild/hermes.js b/packages/react-native/scripts/ios-prebuild/hermes.js index b5b5df656324..3ce8d8195cd9 100644 --- a/packages/react-native/scripts/ios-prebuild/hermes.js +++ b/packages/react-native/scripts/ios-prebuild/hermes.js @@ -19,7 +19,7 @@ const pipeline = promisify(stream.pipeline); const hermesLog = createLogger('Hermes'); const MAVEN_CENTRAL_REPOSITORY = 'https://repo1.maven.org/maven2'; const REACT_NATIVE_MAVEN_CACHE_REPOSITORY = 'https://rnmaven.swmtest.xyz'; -const artifactExistenceCache = new Map(); +const artifactExistenceCache /*: Map */ = new Map(); /*:: import type {BuildFlavor, Destination, Platform} from './types'; @@ -243,8 +243,9 @@ function getMavenRepositoryUrls() /*: Array */ { async function hermesArtifactExists( tarballUrl /*: string */, ) /*: Promise */ { - if (artifactExistenceCache.has(tarballUrl)) { - return artifactExistenceCache.get(tarballUrl); + const cached = artifactExistenceCache.get(tarballUrl); + if (cached != null) { + return cached; } try { diff --git a/packages/react-native/scripts/ios-prebuild/reactNativeDependencies.js b/packages/react-native/scripts/ios-prebuild/reactNativeDependencies.js index dcd6c02ae87a..620248abb00b 100644 --- a/packages/react-native/scripts/ios-prebuild/reactNativeDependencies.js +++ b/packages/react-native/scripts/ios-prebuild/reactNativeDependencies.js @@ -22,7 +22,7 @@ const pipeline = promisify(stream.pipeline); const dependencyLog = createLogger('ReactNativeDependencies'); const MAVEN_CENTRAL_REPOSITORY = 'https://repo1.maven.org/maven2'; const REACT_NATIVE_MAVEN_CACHE_REPOSITORY = 'https://rnmaven.swmtest.xyz'; -const artifactExistenceCache = new Map(); +const artifactExistenceCache /*: Map */ = new Map(); /** * Downloads ReactNativeDependencies artifacts from the specified version and build type. If you want to specify a specific @@ -250,8 +250,9 @@ async function getNightlyTarballUrl( async function reactNativeDependenciesArtifactExists( tarballUrl /*: string */, ) /*: Promise */ { - if (artifactExistenceCache.has(tarballUrl)) { - return artifactExistenceCache.get(tarballUrl); + const cached = artifactExistenceCache.get(tarballUrl); + if (cached != null) { + return cached; } try { From 4ce6cd378deee0351a41a719f2719c79e64b7f81 Mon Sep 17 00:00:00 2001 From: Dawid Malecki Date: Fri, 26 Jun 2026 10:05:05 +0200 Subject: [PATCH 5/7] undo hermes-compiler version change --- packages/react-native/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native/package.json b/packages/react-native/package.json index ddf4b98c998a..ec26182439fe 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -167,7 +167,7 @@ "base64-js": "^1.5.1", "commander": "^12.0.0", "flow-enums-runtime": "^0.0.6", - "hermes-compiler": "250829098.0.14", + "hermes-compiler": "0.0.0", "invariant": "^2.2.4", "memoize-one": "^5.0.0", "metro-runtime": "^0.84.3", From 479acf192d7619fd8657392d970033b12385224a Mon Sep 17 00:00:00 2001 From: Dawid Malecki Date: Fri, 26 Jun 2026 11:23:42 +0200 Subject: [PATCH 6/7] Add reactNativeMavenCacheEnabled flag for toggling usage of Maven cache repo --- .../facebook/react/utils/DependencyUtils.kt | 13 ++++++++- .../com/facebook/react/utils/PropertyUtils.kt | 4 +++ .../react/utils/DependencyUtilsTest.kt | 16 +++++++++++ .../react-native/scripts/cocoapods/rncore.rb | 13 ++++++++- .../scripts/cocoapods/rndependencies.rb | 13 ++++++++- .../scripts/ios-prebuild/hermes.js | 15 +--------- .../ios-prebuild/reactNativeDependencies.js | 19 ++++--------- .../scripts/ios-prebuild/utils.js | 28 +++++++++++++++++++ .../sdks/hermes-engine/hermes-utils.rb | 13 ++++++++- 9 files changed, 102 insertions(+), 32 deletions(-) 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 4ee5651cf612..900acb417b05 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 @@ -14,6 +14,7 @@ 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_REACT_NATIVE_MAVEN_CACHE_ENABLED 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 @@ -76,7 +77,10 @@ internal object DependencyUtils { repo.content { it.excludeGroup("org.webkit") } } } - if (!hasProperty(INTERNAL_REACT_NATIVE_MAVEN_LOCAL_REPO)) { + // The React Native Maven cache must be added before Maven Central so it can serve cached + // artifacts first, while Maven Central remains the fallback. + if (!hasProperty(INTERNAL_REACT_NATIVE_MAVEN_LOCAL_REPO) && + isReactNativeMavenCacheEnabled()) { mavenRepoFromUrl(REACT_NATIVE_MAVEN_CACHE_URL) { repo -> repo.content { it.includeGroupByRegex("com\\.facebook\\.react.*") @@ -280,6 +284,13 @@ internal object DependencyUtils { else -> INCLUDE_JITPACK_REPOSITORY_DEFAULT } + internal fun Project.isReactNativeMavenCacheEnabled(): Boolean = + when { + hasProperty(INTERNAL_REACT_NATIVE_MAVEN_CACHE_ENABLED) -> + property(INTERNAL_REACT_NATIVE_MAVEN_CACHE_ENABLED).toString().toBoolean() + else -> true + } + internal fun String.isNightly(): Boolean = this.startsWith("0.0.0") || "-nightly-" in this internal fun Project.exclusiveEnterpriseRepository() = 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 a35e5f37c5d1..111f1439128d 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 @@ -62,6 +62,10 @@ object PropertyUtils { */ const val INTERNAL_REACT_NATIVE_MAVEN_LOCAL_REPO = "react.internal.mavenLocalRepo" + /** Internal property that controls whether the React Native Maven cache is enabled. */ + const val INTERNAL_REACT_NATIVE_MAVEN_CACHE_ENABLED = + "react.internal.reactNativeMavenCacheEnabled" + /** * Internal property used to specify where the Windows Bash executable is located. This is useful * for contributors who are running Windows on their machine. 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 7726c9a0f265..83dae9725d07 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 @@ -272,6 +272,22 @@ class DependencyUtilsTest { .isNull() } + @Test + fun configureRepositories_withReactNativeMavenCacheDisabled_doesNotContainMavenCache() { + val mavenCacheURI = URI.create("https://rnmaven.swmtest.xyz/") + val project = createProject() + project.extensions.extraProperties.set("react.internal.reactNativeMavenCacheEnabled", "false") + + configureRepositories(project, false) + + assertThat( + project.repositories.firstOrNull { + it is MavenArtifactRepository && it.url == mavenCacheURI + } + ) + .isNull() + } + @Test fun configureRepositories_snapshotRepoHasHigherPriorityThanMavenCentral() { val repositoryURI = URI.create("https://central.sonatype.com/repository/maven-snapshots/") diff --git a/packages/react-native/scripts/cocoapods/rncore.rb b/packages/react-native/scripts/cocoapods/rncore.rb index afa93dd05dea..f7bf6eeaca27 100644 --- a/packages/react-native/scripts/cocoapods/rncore.rb +++ b/packages/react-native/scripts/cocoapods/rncore.rb @@ -387,7 +387,18 @@ def self.maven_repository_urls() return [ENV['ENTERPRISE_REPOSITORY'].delete_suffix("/")] end - return [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY] + # Keep the React Native Maven cache before Maven Central so cached artifacts are tried first + # and Maven Central remains the fallback. + return react_native_maven_cache_enabled? ? + [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY] : + [MAVEN_CENTRAL_REPOSITORY] + end + + def self.react_native_maven_cache_enabled?() + value = ENV['RCT_REACT_NATIVE_MAVEN_CACHE_ENABLED'] + return true if value == nil || value == "" + + value.downcase != "false" && value != "0" end def self.nightly_tarball_url(version, configuration, dsyms = false) diff --git a/packages/react-native/scripts/cocoapods/rndependencies.rb b/packages/react-native/scripts/cocoapods/rndependencies.rb index 9555f819658e..659387924444 100644 --- a/packages/react-native/scripts/cocoapods/rndependencies.rb +++ b/packages/react-native/scripts/cocoapods/rndependencies.rb @@ -186,7 +186,18 @@ def self.maven_repository_urls() return [ENV['ENTERPRISE_REPOSITORY'].delete_suffix("/")] end - return [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY] + # Keep the React Native Maven cache before Maven Central so cached artifacts are tried first + # and Maven Central remains the fallback. + return react_native_maven_cache_enabled? ? + [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY] : + [MAVEN_CENTRAL_REPOSITORY] + end + + def self.react_native_maven_cache_enabled?() + value = ENV['RCT_REACT_NATIVE_MAVEN_CACHE_ENABLED'] + return true if value == nil || value == "" + + value.downcase != "false" && value != "0" end def self.nightly_tarball_url(version, build_type) diff --git a/packages/react-native/scripts/ios-prebuild/hermes.js b/packages/react-native/scripts/ios-prebuild/hermes.js index 3ce8d8195cd9..c92848c458ba 100644 --- a/packages/react-native/scripts/ios-prebuild/hermes.js +++ b/packages/react-native/scripts/ios-prebuild/hermes.js @@ -8,7 +8,7 @@ * @format */ -const {createLogger} = require('./utils'); +const {createLogger, getMavenRepositoryUrls} = require('./utils'); const {execSync} = require('child_process'); const fs = require('fs'); const path = require('path'); @@ -17,8 +17,6 @@ const {promisify} = require('util'); const pipeline = promisify(stream.pipeline); const hermesLog = createLogger('Hermes'); -const MAVEN_CENTRAL_REPOSITORY = 'https://repo1.maven.org/maven2'; -const REACT_NATIVE_MAVEN_CACHE_REPOSITORY = 'https://rnmaven.swmtest.xyz'; const artifactExistenceCache /*: Map */ = new Map(); /*:: @@ -226,17 +224,6 @@ function getTarballUrls( ); } -function getMavenRepositoryUrls() /*: Array */ { - // You can use the `ENTERPRISE_REPOSITORY` variable to customise the base url from which artifacts will be downloaded. - // The mirror's structure must be the same of the Maven repo the react-native core team publishes on Maven Central. - const enterpriseRepository = process.env.ENTERPRISE_REPOSITORY; - if (enterpriseRepository != null && enterpriseRepository !== '') { - return [enterpriseRepository.replace(/\/+$/, '')]; - } - - return [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY]; -} - /** * Checks if a Hermes artifact exists at the given URL using fetch instead of curl */ diff --git a/packages/react-native/scripts/ios-prebuild/reactNativeDependencies.js b/packages/react-native/scripts/ios-prebuild/reactNativeDependencies.js index 620248abb00b..05f2b6c18cc4 100644 --- a/packages/react-native/scripts/ios-prebuild/reactNativeDependencies.js +++ b/packages/react-native/scripts/ios-prebuild/reactNativeDependencies.js @@ -10,7 +10,11 @@ /*:: import type {BuildFlavor} from './types'; */ -const {computeNightlyTarballURL, createLogger} = require('./utils'); +const { + computeNightlyTarballURL, + createLogger, + getMavenRepositoryUrls, +} = require('./utils'); const {execSync} = require('child_process'); const fs = require('fs'); const path = require('path'); @@ -20,8 +24,6 @@ const {promisify} = require('util'); const pipeline = promisify(stream.pipeline); const dependencyLog = createLogger('ReactNativeDependencies'); -const MAVEN_CENTRAL_REPOSITORY = 'https://repo1.maven.org/maven2'; -const REACT_NATIVE_MAVEN_CACHE_REPOSITORY = 'https://rnmaven.swmtest.xyz'; const artifactExistenceCache /*: Map */ = new Map(); /** @@ -217,17 +219,6 @@ function getTarballUrls( ); } -function getMavenRepositoryUrls() /*: Array */ { - // You can use the `ENTERPRISE_REPOSITORY` variable to customise the base url from which artifacts will be downloaded. - // The mirror's structure must be the same of the Maven repo the react-native core team publishes on Maven Central. - const enterpriseRepository = process.env.ENTERPRISE_REPOSITORY; - if (enterpriseRepository != null && enterpriseRepository !== '') { - return [enterpriseRepository.replace(/\/+$/, '')]; - } - - return [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY]; -} - async function getNightlyTarballUrl( version /*: string */, buildType /*: BuildFlavor */, diff --git a/packages/react-native/scripts/ios-prebuild/utils.js b/packages/react-native/scripts/ios-prebuild/utils.js index d1c60f838b52..6e017aa90152 100644 --- a/packages/react-native/scripts/ios-prebuild/utils.js +++ b/packages/react-native/scripts/ios-prebuild/utils.js @@ -13,6 +13,9 @@ const {execSync} = require('child_process'); const fs = require('fs'); +const MAVEN_CENTRAL_REPOSITORY = 'https://repo1.maven.org/maven2'; +const REACT_NATIVE_MAVEN_CACHE_REPOSITORY = 'https://rnmaven.swmtest.xyz'; + /** * Creates a folder if it does not exist * @param {string} folderPath - The path to the folder @@ -102,9 +105,34 @@ async function computeNightlyTarballURL( return finalUrl; } +function getMavenRepositoryUrls() /*: Array */ { + // You can use the `ENTERPRISE_REPOSITORY` variable to customise the base url from which artifacts will be downloaded. + // The mirror's structure must be the same of the Maven repo the react-native core team publishes on Maven Central. + const enterpriseRepository = process.env.ENTERPRISE_REPOSITORY; + if (enterpriseRepository != null && enterpriseRepository !== '') { + return [enterpriseRepository.replace(/\/+$/, '')]; + } + + // Keep the React Native Maven cache before Maven Central so cached artifacts are tried first + // and Maven Central remains the fallback. + return isReactNativeMavenCacheEnabled() + ? [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY] + : [MAVEN_CENTRAL_REPOSITORY]; +} + +function isReactNativeMavenCacheEnabled() /*: boolean */ { + const value = process.env.RCT_REACT_NATIVE_MAVEN_CACHE_ENABLED; + if (value == null || value === '') { + return true; + } + + return value.toLowerCase() !== 'false' && value !== '0'; +} + module.exports = { createFolderIfNotExists, throwIfOnEden, createLogger, computeNightlyTarballURL, + getMavenRepositoryUrls, }; diff --git a/packages/react-native/sdks/hermes-engine/hermes-utils.rb b/packages/react-native/sdks/hermes-engine/hermes-utils.rb index f05c98c59165..e48657238399 100644 --- a/packages/react-native/sdks/hermes-engine/hermes-utils.rb +++ b/packages/react-native/sdks/hermes-engine/hermes-utils.rb @@ -212,7 +212,18 @@ def maven_repository_urls() return [ENV['ENTERPRISE_REPOSITORY'].delete_suffix("/")] end - return [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY] + # Keep the React Native Maven cache before Maven Central so cached artifacts are tried first + # and Maven Central remains the fallback. + return react_native_maven_cache_enabled? ? + [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY] : + [MAVEN_CENTRAL_REPOSITORY] +end + +def react_native_maven_cache_enabled?() + value = ENV['RCT_REACT_NATIVE_MAVEN_CACHE_ENABLED'] + return true if value == nil || value == "" + + value.downcase != "false" && value != "0" end def download_stable_hermes(react_native_path, version, configuration) From 60b7f96f6685318211cb200df29c7e1473311fac Mon Sep 17 00:00:00 2001 From: Dawid Malecki Date: Fri, 26 Jun 2026 11:27:26 +0200 Subject: [PATCH 7/7] refactor ruby files --- .../react-native/scripts/cocoapods/rncore.rb | 26 +------------------ .../scripts/cocoapods/rndependencies.rb | 26 +------------------ .../react-native/scripts/cocoapods/utils.rb | 24 +++++++++++++++++ 3 files changed, 26 insertions(+), 50 deletions(-) diff --git a/packages/react-native/scripts/cocoapods/rncore.rb b/packages/react-native/scripts/cocoapods/rncore.rb index f7bf6eeaca27..a0ac7e050d30 100644 --- a/packages/react-native/scripts/cocoapods/rncore.rb +++ b/packages/react-native/scripts/cocoapods/rncore.rb @@ -44,9 +44,6 @@ def add_rncore_dependency(s) ## - RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS: If set to 1, it will download the dSYMs for the prebuilt RNCore frameworks and install these in the framework folders class ReactNativeCoreUtils - MAVEN_CENTRAL_REPOSITORY = "https://repo1.maven.org/maven2" - REACT_NATIVE_MAVEN_CACHE_REPOSITORY = "https://rnmaven.swmtest.xyz" - @@build_from_source = true @@react_native_path = "" @@react_native_version = "" @@ -373,34 +370,13 @@ def self.stable_tarball_url(version, build_type, dsyms = false) def self.stable_tarball_urls(version, build_type, dsyms = false) group = "com/facebook/react" - return maven_repository_urls().map { |maven_repo_url| + return ReactNativePodsUtils.maven_repository_urls().map { |maven_repo_url| # Sample url from Maven: # https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.81.0/react-native-artifacts-0.81.0-reactnative-core-debug.tar.gz "#{maven_repo_url}/#{group}/react-native-artifacts/#{version}/react-native-artifacts-#{version}-reactnative-core-#{dsyms ? "dSYM-" : ""}#{build_type.to_s}.tar.gz" } end - def self.maven_repository_urls() - ## You can use the `ENTERPRISE_REPOSITORY` variable to customise the base url from which artifacts will be downloaded. - ## The mirror's structure must be the same of the Maven repo the react-native core team publishes on Maven Central. - if ENV['ENTERPRISE_REPOSITORY'] != nil && ENV['ENTERPRISE_REPOSITORY'] != "" - return [ENV['ENTERPRISE_REPOSITORY'].delete_suffix("/")] - end - - # Keep the React Native Maven cache before Maven Central so cached artifacts are tried first - # and Maven Central remains the fallback. - return react_native_maven_cache_enabled? ? - [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY] : - [MAVEN_CENTRAL_REPOSITORY] - end - - def self.react_native_maven_cache_enabled?() - value = ENV['RCT_REACT_NATIVE_MAVEN_CACHE_ENABLED'] - return true if value == nil || value == "" - - value.downcase != "false" && value != "0" - end - def self.nightly_tarball_url(version, configuration, dsyms = false) artefact_coordinate = "react-native-artifacts" artefact_name = "reactnative-core-#{dsyms ? "dSYM-" : ""}#{configuration ? configuration : "debug"}.tar.gz" diff --git a/packages/react-native/scripts/cocoapods/rndependencies.rb b/packages/react-native/scripts/cocoapods/rndependencies.rb index 659387924444..619244b4491b 100644 --- a/packages/react-native/scripts/cocoapods/rndependencies.rb +++ b/packages/react-native/scripts/cocoapods/rndependencies.rb @@ -57,9 +57,6 @@ def add_rn_third_party_dependencies(s) end class ReactNativeDependenciesUtils - MAVEN_CENTRAL_REPOSITORY = "https://repo1.maven.org/maven2" - REACT_NATIVE_MAVEN_CACHE_REPOSITORY = "https://rnmaven.swmtest.xyz" - @@build_from_source = true @@react_native_path = "" @@react_native_version = "" @@ -174,32 +171,11 @@ def self.release_tarball_url(version, build_type) def self.release_tarball_urls(version, build_type) group = "com/facebook/react" - return maven_repository_urls().map { |maven_repo_url| + return ReactNativePodsUtils.maven_repository_urls().map { |maven_repo_url| "#{maven_repo_url}/#{group}/react-native-artifacts/#{version}/react-native-artifacts-#{version}-reactnative-dependencies-#{build_type.to_s}.tar.gz" } end - def self.maven_repository_urls() - ## You can use the `ENTERPRISE_REPOSITORY` variable to customise the base url from which artifacts will be downloaded. - ## The mirror's structure must be the same of the Maven repo the react-native core team publishes on Maven Central. - if ENV['ENTERPRISE_REPOSITORY'] != nil && ENV['ENTERPRISE_REPOSITORY'] != "" - return [ENV['ENTERPRISE_REPOSITORY'].delete_suffix("/")] - end - - # Keep the React Native Maven cache before Maven Central so cached artifacts are tried first - # and Maven Central remains the fallback. - return react_native_maven_cache_enabled? ? - [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY] : - [MAVEN_CENTRAL_REPOSITORY] - end - - def self.react_native_maven_cache_enabled?() - value = ENV['RCT_REACT_NATIVE_MAVEN_CACHE_ENABLED'] - return true if value == nil || value == "" - - value.downcase != "false" && value != "0" - end - def self.nightly_tarball_url(version, build_type) artifact_coordinate = "react-native-artifacts" artifact_name = "reactnative-dependencies-#{build_type.to_s}.tar.gz" diff --git a/packages/react-native/scripts/cocoapods/utils.rb b/packages/react-native/scripts/cocoapods/utils.rb index 0e388d6a7ef5..98602455a672 100644 --- a/packages/react-native/scripts/cocoapods/utils.rb +++ b/packages/react-native/scripts/cocoapods/utils.rb @@ -12,11 +12,35 @@ # Utilities class for React Native Cocoapods class ReactNativePodsUtils + MAVEN_CENTRAL_REPOSITORY = "https://repo1.maven.org/maven2" + REACT_NATIVE_MAVEN_CACHE_REPOSITORY = "https://rnmaven.swmtest.xyz" + # URI::File.build validates path components as ASCII, so escape the filesystem path first. def self.local_file_uri(path) URI::File.build(path: URI::DEFAULT_PARSER.escape(path)).to_s end + def self.maven_repository_urls() + ## You can use the `ENTERPRISE_REPOSITORY` variable to customise the base url from which artifacts will be downloaded. + ## The mirror's structure must be the same of the Maven repo the react-native core team publishes on Maven Central. + if ENV['ENTERPRISE_REPOSITORY'] != nil && ENV['ENTERPRISE_REPOSITORY'] != "" + return [ENV['ENTERPRISE_REPOSITORY'].delete_suffix("/")] + end + + # Keep the React Native Maven cache before Maven Central so cached artifacts are tried first + # and Maven Central remains the fallback. + return react_native_maven_cache_enabled? ? + [REACT_NATIVE_MAVEN_CACHE_REPOSITORY, MAVEN_CENTRAL_REPOSITORY] : + [MAVEN_CENTRAL_REPOSITORY] + end + + def self.react_native_maven_cache_enabled?() + value = ENV['RCT_REACT_NATIVE_MAVEN_CACHE_ENABLED'] + return true if value == nil || value == "" + + value.downcase != "false" && value != "0" + end + def self.warn_if_not_on_arm64 if SysctlChecker.new().call_sysctl_arm64() == 1 && !Environment.new().ruby_platform().include?('arm64') Pod::UI.warn 'Do not use "pod install" from inside Rosetta2 (x86_64 emulation on arm64).'