Skip to content

Commit

Permalink
Fix react-native nightly test (#19805)
Browse files Browse the repository at this point in the history
# Why

Fix broken react-native nightly test

# How

- meta ships nightly build binaries on maven central now, we could just use the binaries than building from source. the ci job time reduces dramatically. previously it takes almost four hours, now it takes 51m for android and 60m for ios.
- use env `REACT_NATIVE_OVERRIDE_VERSION` to override the version rather than hardcoded 9999.9999.9999 in packages.
- expo-modules-core / expo-av / expo-gl - support to download snapshot react-native from maven central
- fix some breaking changes from react-native nightly
  - expo-dev-launcher: `RCTAsyncLocalStorage` is removed
  - expo-modules-core: remove deprecated `<hermes/hermes.h>` import
  - expo-modules-core: `RCTAppSetupDefaultRootView` has new parameter
  - expo: `com.facebook.react.uimanager.UIImplementationProvider` is removed
- bare-expo `reactNativeNightly` gradle property is unused now, just rename to `buildReactNativeFromSource` if someone want to use.
- [tools] update SetupReactNativeNightly

# Test Plan

- test suite nightly ci passed
- original test suite ci passed to make sure compatibility with sdk 47
  • Loading branch information
Kudo committed Nov 3, 2022
1 parent a2c81d9 commit e68edf7
Show file tree
Hide file tree
Showing 32 changed files with 541 additions and 186 deletions.
98 changes: 72 additions & 26 deletions .github/workflows/test-suite-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,15 @@ concurrency:
cancel-in-progress: true

jobs:
android-ios:
ios:
runs-on: macos-11
env:
ORG_GRADLE_PROJECT_reactNativeArchitectures: x86_64
GRADLE_OPTS: -Dorg.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=2048m
REACT_NATIVE_OVERRIDE_VERSION: 9999.9999.9999
steps:
- name: 👀 Checkout
uses: actions/checkout@v3
with:
submodules: true
- name: ⬢ Setup Node
uses: actions/setup-node@v3
with:
node-version: '14.17'
- name: 🔨 Use JDK 11
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '11'
- name: 🔨 Switch to Xcode 13.2.1
run: sudo xcode-select --switch /Applications/Xcode_13.2.1.app
- name: 🍺 Install required tools
Expand All @@ -53,10 +43,7 @@ jobs:
uses: ./.github/actions/expo-caches
id: expo-caches
with:
yarn-workspace: 'true'
yarn-tools: 'true'
avd: 'true'
avd-api: 31
- name: ⚙️ Setup react-native nightly
run: et setup-react-native-nightly
- name: ⚛️ Display React Native config
Expand All @@ -67,7 +54,7 @@ jobs:
working-directory: apps/bare-expo/ios
- name: 🥥 Install pods in apps/bare-expo/ios
run: |
rm -f Podfile.lock
pod update hermes-engine --no-repo-update
pod install
working-directory: apps/bare-expo/ios
- name: 🧹 Clean Detox
Expand All @@ -79,36 +66,95 @@ jobs:
- name: 🍏 Run iOS tests
run: yarn ios:detox:test:release
working-directory: apps/bare-expo
- name: Store images of build failures
if: always()
uses: actions/upload-artifact@v3
with:
name: bare-expo-artifacts
path: apps/bare-expo/artifacts
- name: 🔔 Notify on Slack
uses: 8398a7/action-slack@v3
if: failure() && (github.event_name == 'schedule' || github.event.ref == 'refs/heads/main')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SLACK_WEBHOOK_URL: ${{ secrets.slack_webhook_ios }}
with:
channel: '#expo-ios'
status: ${{ job.status }}
fields: job,message,ref,eventName,author,took
author_name: Test Suite Nightly (iOS)

android:
runs-on: macos-11
env:
ORG_GRADLE_PROJECT_reactNativeArchitectures: x86_64
GRADLE_OPTS: -Dorg.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=2048m
REACT_NATIVE_OVERRIDE_VERSION: 9999.9999.9999
strategy:
matrix:
api-level: [31]
steps:
- name: 👀 Checkout
uses: actions/checkout@v3
with:
submodules: true
- name: ⬢ Setup Node
uses: actions/setup-node@v3
with:
node-version: '14.17'
- name: 🔨 Use JDK 11
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '11'
- name: 🍺 Install required tools
run: brew install watchman
- name: ➕ Add `bin` to GITHUB_PATH
run: echo "$(pwd)/bin" >> $GITHUB_PATH
- name: ♻️ Restore caches
uses: ./.github/actions/expo-caches
id: expo-caches
with:
yarn-tools: 'true'
avd: 'true'
avd-api: ${{ matrix.api-level }}
- name: ⚙️ Setup react-native nightly
run: et setup-react-native-nightly
- name: ⚛️ Display React Native config
run: yarn react-native config
working-directory: apps/bare-expo
- name: 🧹 Clean Detox
run: yarn detox:clean
working-directory: apps/bare-expo
- name: 🤖 Build Android project for Detox
run: |
pushd android && ./gradlew :ReactAndroid:hermes-engine:assembleDebug && popd
yarn android:detox:build:release
run: yarn android:detox:build:release
working-directory: apps/bare-expo
env:
GRADLE_OPTS: '-Dorg.gradle.internal.http.connectionTimeout=180000 -Dorg.gradle.internal.http.socketTimeout=180000 -Dorg.gradle.internal.network.retry.max.attempts=18 -Dorg.gradle.internal.network.retry.initial.backOff=2000'
- name: 🤖 Run Android tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 31
avd-name: avd-31
api-level: ${{ matrix.api-level }}
avd-name: avd-${{ matrix.api-level }}
arch: x86_64
force-avd-creation: false
script: yarn android:detox:test:release
working-directory: ./apps/bare-expo
- name: Store images of build failures
- name: 📸 Store images of build failures
if: always()
uses: actions/upload-artifact@v3
with:
name: bare-expo-artifacts
path: apps/bare-expo/artifacts
- name: 🔔 Notify on Slack
uses: 8398a7/action-slack@v3
if: failure()
if: failure() && (github.event_name == 'schedule' || github.event.ref == 'refs/heads/main')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SLACK_WEBHOOK_URL: ${{ secrets.slack_webhook_ios }}
SLACK_WEBHOOK_URL: ${{ secrets.slack_webhook_android }}
MATRIX_CONTEXT: ${{ toJson(matrix) }}
with:
channel: '#expo-ios'
channel: '#expo-android'
status: ${{ job.status }}
fields: job,message,ref,eventName,author,took
author_name: Test Suite Nightly
author_name: Test Suite Nightly (Android)
2 changes: 1 addition & 1 deletion apps/bare-expo/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ dependencies {
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
}

if (isNewArchitectureEnabled() || findProperty("reactNativeNightly") == "true") {
if (isNewArchitectureEnabled() || findProperty("buildReactNativeFromSource") == "true") {
// If new architecture is enabled, we let you build RN from source
// Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
// This will be applied to all the imported transtitive dependency.
Expand Down
8 changes: 7 additions & 1 deletion apps/bare-expo/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ ext {
allprojects {
// [Custom]
configurations.all {
if (findProperty("reactNativeNightly") == "true") {
if (findProperty("buildReactNativeFromSource") == "true") {
resolutionStrategy {
dependencySubstitution {
substitute module("com.facebook.react:react-native:+") with project(":ReactAndroid")
Expand Down Expand Up @@ -97,6 +97,12 @@ allprojects {
excludeGroup "com.facebook.react"
}
}
maven {
url 'https://oss.sonatype.org/content/repositories/snapshots/'
content {
includeGroup "com.facebook.react"
}
}
maven { url 'https://jitpack.io' }
}
}
Expand Down
2 changes: 1 addition & 1 deletion apps/bare-expo/android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ rootProject.name = 'BareExpo'
include ':app'
includeBuild(new File(["node", "--print", "require.resolve('react-native-gradle-plugin/package.json')"].execute(null, rootDir).text.trim()).getParentFile())

if ((settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") || (settings.hasProperty("reactNativeNightly") && settings.reactNativeNightly == "true")) {
if ((settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") || (settings.hasProperty("buildReactNativeFromSource") && settings.buildReactNativeFromSource == "true")) {
include(":ReactAndroid")
project(":ReactAndroid").projectDir = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../ReactAndroid");
include(":ReactAndroid:hermes-engine")
Expand Down
3 changes: 2 additions & 1 deletion apps/test-suite/components/Suites.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ export default function Suites({ suites, done, numFailed, results }) {

const scrollToEnd = React.useMemo(
() => () => {
if (ref.current) ref.current.scrollToEnd({ animated: false });
if (ref.current && ref.current.props.data.length > 0)
ref.current.scrollToEnd({ animated: false });
},
[ref]
);
Expand Down
2 changes: 2 additions & 0 deletions packages/expo-av/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

### 🐛 Bug fixes

- Fixed build errors when testing on React Native nightly builds. ([#19805](https://github.com/expo/expo/pull/19805) by [@kudo](https://github.com/kudo))

### 💡 Others

## 13.0.1 — 2022-10-30
Expand Down
70 changes: 49 additions & 21 deletions packages/expo-av/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,26 @@ import java.nio.file.Paths
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'maven-publish'
apply plugin: "de.undercouch.download"

group = 'host.exp.exponent'
version = '13.0.1'

def REACT_NATIVE_DIR = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).parent
def RN_BUILD_FROM_SOURCE = findProject(":ReactAndroid") != null
def RN_SO_DIR = RN_BUILD_FROM_SOURCE
? Paths.get(findProject(":ReactAndroid").getProjectDir().toString(), "build", "intermediates", "library_*", "*", "jni")
: "${buildDir}/react-native-0*/jni"
def RN_AAR_DIR = "${REACT_NATIVE_DIR}/android"
def customDownloadsDir = System.getenv("REACT_NATIVE_DOWNLOADS_DIR")
def downloadsDir = customDownloadsDir ? new File(customDownloadsDir) : new File("$buildDir/downloads")

def REACT_NATIVE_BUILD_FROM_SOURCE = findProject(":ReactAndroid") != null
def REACT_NATIVE_DIR = REACT_NATIVE_BUILD_FROM_SOURCE
? findProject(":ReactAndroid").getProjectDir().parent
: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).parent
def RN_SO_DIR = REACT_NATIVE_BUILD_FROM_SOURCE
? Paths.get(findProject(":ReactAndroid").getProjectDir().toString(), "build", "intermediates", "library_*", "*", "jni")
: "${buildDir}/react-native.aar/jni"

def reactProperties = new Properties()
file("$REACT_NATIVE_DIR/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
def reactNativeIsNightly = reactProperties.getProperty("VERSION_NAME").startsWith("0.0.0-")

def reactNativeArchitectures() {
def value = project.getProperties().get("reactNativeArchitectures")
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
Expand Down Expand Up @@ -45,6 +55,7 @@ buildscript {

dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}")
classpath("de.undercouch:gradle-download-task:5.3.0")
}
}

Expand Down Expand Up @@ -170,27 +181,44 @@ dependencies {
testImplementation 'io.mockk:mockk:1.12.3'
}

def downloadReactNativeNightlyAAR = { buildType, version, downloadFile ->
def classifier = buildType == 'Debug' ? 'debug' : 'release'
download.run {
src("https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=com.facebook.react&a=react-native&c=${classifier}&e=aar&v=${version}-SNAPSHOT")
onlyIfNewer(true)
overwrite(false)
dest(downloadFile)
}
}

def extractReactNativeAAR = { buildType ->
def suffix = buildType == 'Debug' ? '-debug' : '-release'
def rnAARs = fileTree(RN_AAR_DIR).matching { include "**/react-native/**/*${suffix}.aar" }
if (rnAARs.isEmpty()) {
rnAARs = fileTree(RN_AAR_DIR).matching { include "**/react-native/**/*.aar" }
}
if (rnAARs.any()) {
// node_modules/react-native has a .aar, extract headers
if (rnAARs.size() > 1) {
logger.error("More than one React Native AAR file has been found:")
rnAARs.each {println(it) }
throw new GradleException("Multiple React Native AARs found:\n${rnAARs.join("\n")}" +
"\nRemove the old ones and try again")
def rnAAR
if (reactNativeIsNightly) {
def downloadFile = file("${downloadsDir}/react-native-nightly.aar")
downloadReactNativeNightlyAAR(buildType, reactProperties.getProperty("VERSION_NAME"), downloadFile)
rnAAR = downloadFile
} else {
def rnAARs = fileTree(REACT_NATIVE_DIR).matching { include "**/react-native/**/*${suffix}.aar" }
if (rnAARs.isEmpty()) {
rnAARs = fileTree(REACT_NATIVE_DIR).matching { include "**/react-native/**/*.aar" }
}
if (rnAARs.any()) {
// node_modules/react-native has a .aar, extract headers
if (rnAARs.size() > 1) {
logger.error("More than one React Native AAR file has been found:")
rnAARs.each {println(it) }
throw new GradleException("Multiple React Native AARs found:\n${rnAARs.join("\n")}" +
"\nRemove the old ones and try again")
}
}
rnAAR = rnAARs.singleFile
}
def rnAAR = rnAARs.singleFile
def file = rnAAR.absoluteFile
def packageName = file.name.tokenize('-')[0]
copy {
from zipTree(file)
into "$buildDir/$file.name"
into "$buildDir/react-native.aar"
include "jni/**/*"
}
}
Expand Down Expand Up @@ -238,12 +266,12 @@ tasks.whenTaskAdded { task ->
def buildType = task.name.endsWith('Debug') ? 'Debug' : 'Release'
task.dependsOn(extractAARHeaders)
task.dependsOn(extractJNIFiles)
if (RN_BUILD_FROM_SOURCE) {
if (REACT_NATIVE_BUILD_FROM_SOURCE) {
task.dependsOn(":ReactAndroid:copy${buildType}JniLibsProjectOnly")
} else {
task.dependsOn("extractReactNativeAAR${buildType}")
}
} else if (task.name.startsWith('generateJsonModel') && RN_BUILD_FROM_SOURCE) {
} else if (task.name.startsWith('generateJsonModel') && REACT_NATIVE_BUILD_FROM_SOURCE) {
def buildType = task.name.endsWith('Debug') ? 'Debug' : 'Release'
task.dependsOn(":ReactAndroid:copy${buildType}JniLibsProjectOnly")
}
Expand Down
2 changes: 1 addition & 1 deletion packages/expo-dev-launcher/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

### 🐛 Bug fixes

- Fixed build errors when testing on React Native nightly builds. ([#19369](https://github.com/expo/expo/pull/19369) by [@kudo](https://github.com/kudo))
- Fixed build errors when testing on React Native nightly builds. ([#19369](https://github.com/expo/expo/pull/19369) by [@kudo](https://github.com/kudo), [#19805](https://github.com/expo/expo/pull/19805) by [@kudo](https://github.com/kudo))

### 💡 Others

Expand Down
18 changes: 12 additions & 6 deletions packages/expo-dev-launcher/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,18 @@ def getNodeModulesPackageVersion(packageName, overridePropName) {
}

def getRNVersion() {
def versionNumber = getNodeModulesPackageVersion("react-native", "reactNativeVersion")
if (versionNumber == versionToNumber(0, 0, 0)) {
// react-native nightly build published as `0.0.0-20221002-2027-2319f75c8` form, but its semantic is latest
return versionToNumber(9999, 9999, 9999)
}
return versionNumber
if (System.getenv("REACT_NATIVE_OVERRIDE_VERSION")) {
def version = System.getenv("REACT_NATIVE_OVERRIDE_VERSION")
def coreVersion = version.split("-")[0]
def (major, minor, patch) = coreVersion.tokenize('.').collect { it.toInteger() }
return versionToNumber(
major,
minor,
patch
)
}

return getNodeModulesPackageVersion("react-native", "reactNativeVersion")
}

def getExpoPackageVersion() {
Expand Down
2 changes: 0 additions & 2 deletions packages/expo-dev-launcher/ios/EXDevLauncherController.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#import <React/RCTRootView.h>
#import <React/RCTDevLoadingViewSetEnabled.h>
#import <React/RCTDevMenu.h>
#import <React/RCTAsyncLocalStorage.h>
#import <React/RCTDevSettings.h>
#import <React/RCTRootContentView.h>
#import <React/RCTAppearance.h>
Expand Down Expand Up @@ -89,7 +88,6 @@ - (instancetype)init {
NSMutableArray *modules = [[DevMenuVendoredModulesUtils vendoredModules:bridge addReanimated2:FALSE] mutableCopy];

[modules addObject:[RCTDevMenu new]];
[modules addObject:[RCTAsyncLocalStorage new]];
#ifndef EX_DEV_LAUNCHER_URL
[modules addObject:[EXDevLauncherRCTDevSettings new]];
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ class EXDevLauncherControllerTest: QuickSpec {

let modules = module.extraModules(for: nil)!

expect(modules.count).to(equal(10))
expect(modules.count).to(equal(9))
expect(modules.first { $0 is RCTDevMenu }).toNot(beNil())
expect(modules.first { $0 is RCTAsyncLocalStorage }).toNot(beNil())
expect(modules.first { type(of: $0).moduleName() == "DevLoadingView" }).toNot(beNil())
expect(modules.first { type(of: $0).moduleName() == "EXDevLauncherInternal" }).toNot(beNil())

Expand Down
2 changes: 1 addition & 1 deletion packages/expo-dev-menu/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

### 🐛 Bug fixes

- Fixed build errors when testing on React Native nightly builds. ([#19369](https://github.com/expo/expo/pull/19369) by [@kudo](https://github.com/kudo))
- Fixed build errors when testing on React Native nightly builds. ([#19369](https://github.com/expo/expo/pull/19369) by [@kudo](https://github.com/kudo), [#19805](https://github.com/expo/expo/pull/19805) by [@kudo](https://github.com/kudo))

### 💡 Others

Expand Down

0 comments on commit e68edf7

Please sign in to comment.