diff --git a/.github/workflows/install-test-react-native.yml b/.github/workflows/install-test-react-native.yml index deeabd3462..e07ff9edf2 100644 --- a/.github/workflows/install-test-react-native.yml +++ b/.github/workflows/install-test-react-native.yml @@ -14,7 +14,8 @@ defaults: jobs: install: name: Install Test on React Native ${{ matrix.platform == 'ios' && 'iOS' || 'Android' }} realm@${{ matrix.realm-version }}, react-native@${{ matrix.react-native-version }} new architecture ${{ matrix.new-architecture && 'enabled' || 'disabled' }} running ${{ matrix.engine }} - runs-on: macos-12 + # macos-13-xlarge is an M1 mac (which has no Android SDK) + runs-on: ${{ matrix.platform == 'ios' && 'macos-13-xlarge' || 'macos-13-large' }} timeout-minutes: 120 strategy: fail-fast: false @@ -23,9 +24,9 @@ jobs: - ios - android realm-version: - - v11 # Enable if we feel the need + - v11 # For the last major version - latest - # - next + #- next # For release candidates react-native-version: - latest - next @@ -38,13 +39,10 @@ jobs: - hermes # See https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md#xcode xcode: - # - 14.0.1 - - 13.1 + - 15.0 node: # RN bumped minimum Node version: https://github.com/huntie/react-native/blob/6cb6b81dd1c6b74a0f4bac5b06fa5aef93b48fe4/CHANGELOG.md?plain=1#L15 - 18 - env: - DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 @@ -61,26 +59,18 @@ jobs: - name: Configure ccache run: ccache --set-config="compiler_check=content" - # TODO: Remove if this becomes unneeded in the future - - name: Invoke the simulator (making subsequent "open -a Simulator" calls work) + # Invoke a specific iPhone simulator to ensure AppleTV is not chosen as the default simulator + - uses: futureware-tech/simulator-action@v2 if: ${{ matrix.platform == 'ios' }} - run: open -a ${{ env.DEVELOPER_DIR }}/Contents/Developer/Applications/Simulator.app/Contents/MacOS/Simulator + with: + model: "iPhone 14" - name: Install dependencies of the CLI run: npm ci - name: Initialize app - # Using "--skip-bundle-install" to let the setup-ruby action install the bundle - # Using "--skip-pod-install" to ensure it happens after setup-ruby has executed run: npm run init -- --skip-bundle-install --skip-pod-install --realm-version ${{ matrix.realm-version }} --react-native-version ${{ matrix.react-native-version }} --engine ${{ matrix.engine }} --new-architecture ${{ matrix.new-architecture }} - - uses: ruby/setup-ruby@v1 - if: ${{ matrix.platform == 'ios' }} - with: - ruby-version: '3.0' - bundler-cache: true - working-directory: install-tests/react-native/app - - if: ${{ matrix.platform == 'ios' }} run: pod install working-directory: install-tests/react-native/app/ios @@ -89,7 +79,7 @@ jobs: if: ${{ matrix.platform == 'android' }} with: distribution: 'zulu' - java-version: '11' + java-version: '17' - name: Run test (iOS) if: ${{ matrix.platform == 'ios' }} @@ -103,6 +93,8 @@ jobs: api-level: 29 target: google_apis script: npm test -- --platform android + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: true working-directory: install-tests/react-native slack-workflow-status: diff --git a/install-tests/react-native/README.md b/install-tests/react-native/README.md new file mode 100644 index 0000000000..ab89f42584 --- /dev/null +++ b/install-tests/react-native/README.md @@ -0,0 +1,18 @@ +# How To Use + +There are two commands for the cli tool: +`init` and `test` + +The most common usage is the following: + +`npm run init -- --react-native-version next --realm-version latest` + +This will create the template for latest release candidate of React Native, install the latest publish `realm` package +and patch the install test code necessary for the next step. + +`npm run test -- --platform ios` +`npm run test -- --platform android` + +This will run test for `ios` and `android` respectively. The `init` step is required first (without failures). +This will spawn the app and a server which will be waiting for the application to post a message to. +When the message has been sent, the test will shutdown and return a success code. diff --git a/install-tests/react-native/cli.ts b/install-tests/react-native/cli.ts index b4655c29f8..fc0345a862 100644 --- a/install-tests/react-native/cli.ts +++ b/install-tests/react-native/cli.ts @@ -31,8 +31,7 @@ const DEFAULT_APP_PATH = path.resolve(__dirname, "app"); const PATCHES_PATH = path.resolve(__dirname, "patches"); const APP_JS_PATH = path.resolve(PATCHES_PATH, "App.js"); const CCACHE_PODFILE_PATCH_PATH = path.resolve(PATCHES_PATH, "ccache-Podfile.patch"); -const JSC_PODFILE_PATCH_PATH = path.resolve(PATCHES_PATH, "jsc-Podfile.patch"); -const JSC_BUILD_GRADLE_PATCH_PATH = path.resolve(PATCHES_PATH, "jsc-build.gradle.patch"); +const CCACHE_PODFILE_PATCH_PATH_PRE_73 = path.resolve(PATCHES_PATH, "ccache-Podfile-pre-73.patch"); const PORT = 3000; const TIMEOUT = 5 * 60 * 1000; // 5 min should be plenty of time from app has launched until message gets received @@ -160,26 +159,17 @@ yargs(hideBin(process.argv)) // We're using force to succeed on peer dependency issues exec("npm", ["install", `realm@${realmVersion}`, "--force"], { cwd: appPath }); - const podfilePath = path.resolve(appPath, "ios", "Podfile"); - console.log(`Patching podfile to use ccache (${podfilePath})`); - applyPatch(CCACHE_PODFILE_PATCH_PATH, podfilePath); - const { version: resolvedReactNativeVersion } = readPackageJson( path.resolve(appPath, "node_modules/react-native"), ); - // TODO: Delete this once 0.71.0 or above is latest - if (semver.satisfies(resolvedReactNativeVersion, "<0.71.0")) { - if (engine === "jsc") { - console.log(`Patching Podfile to use JSC (${podfilePath})`); - applyPatch(JSC_PODFILE_PATCH_PATH, podfilePath); + const podfilePath = path.resolve(appPath, "ios", "Podfile"); + console.log(`Patching podfile to use ccache (${podfilePath})`); - const appGradleBuildPath = path.resolve(appPath, "android", "app", "build.gradle"); - console.log(`Patching app/build.gradle to use JSC (${appGradleBuildPath})`); - applyPatch(JSC_BUILD_GRADLE_PATCH_PATH, appGradleBuildPath); - } + if (semver.satisfies(resolvedReactNativeVersion, "<0.73.0")) { + applyPatch(CCACHE_PODFILE_PATCH_PATH_PRE_73, podfilePath); } else { - console.log("Skipping patch of Podfile to use JSC, relying on USE_HERMES env variable instead"); + applyPatch(CCACHE_PODFILE_PATCH_PATH, podfilePath); } // Store Gradle properties for RN >=0.71.0 @@ -234,7 +224,8 @@ yargs(hideBin(process.argv)) process.exit(code || 1); } - const metro = cp.spawn("npx", ["react-native", "start"], { cwd: appPath, stdio: "inherit" }); + // --no-interactive was added to turn off the dev menu, which was throwing an EIO error when the process was killed + const metro = cp.spawn("npx", ["react-native", "start", "--no-interactive"], { cwd: appPath, stdio: "inherit" }); metro.addListener("exit", prematureExitCallback); const server = createServer().listen(PORT); @@ -300,8 +291,20 @@ yargs(hideBin(process.argv)) // Kill metro, in silence metro.removeListener("exit", prematureExitCallback); metro.kill(); + + // Ensure metro is really dead + // If this is removed, it's highly likely the android emulator runner will not shut down correctly + const METRO_PORT = 8081; + cp.exec(`lsof -i :${METRO_PORT} | grep LISTEN | awk '{print $2}' | xargs kill -9`, (error) => { + if (error) { + console.error(`Failed to kill process on port ${PORT}:`, error); + } else { + console.log(`Killed process on port ${PORT}`); + } + }); + // Stop listening for the app - server.close(); + server.close(() => process.exit()); } }, ) diff --git a/install-tests/react-native/patches/ccache-Podfile-pre-73.patch b/install-tests/react-native/patches/ccache-Podfile-pre-73.patch new file mode 100644 index 0000000000..b3524bd719 --- /dev/null +++ b/install-tests/react-native/patches/ccache-Podfile-pre-73.patch @@ -0,0 +1,18 @@ +--- app/ios/Podfile ++++ app/ios/Podfile +@@ -39,5 +39,15 @@ + :mac_catalyst_enabled => false + ) + __apply_Xcode_12_5_M1_post_install_workaround(installer) ++ # Using ccache when building ++ installer.pods_project.targets.each do |target| ++ target.build_configurations.each do |config| ++ # Using the un-qualified names means you can swap in different implementations, for example ccache ++ config.build_settings["CC"] = "clang" ++ config.build_settings["LD"] = "clang" ++ config.build_settings["CXX"] = "clang++" ++ config.build_settings["LDPLUSPLUS"] = "clang++" ++ end ++ end + end + end diff --git a/install-tests/react-native/patches/ccache-Podfile.patch b/install-tests/react-native/patches/ccache-Podfile.patch index b3524bd719..ed35f90912 100644 --- a/install-tests/react-native/patches/ccache-Podfile.patch +++ b/install-tests/react-native/patches/ccache-Podfile.patch @@ -1,9 +1,9 @@ ---- app/ios/Podfile -+++ app/ios/Podfile -@@ -39,5 +39,15 @@ +--- Podfile.copy 2023-10-09 15:29:25 ++++ Podfile 2023-10-09 15:29:42 +@@ -51,5 +51,15 @@ + config[:reactNativePath], :mac_catalyst_enabled => false ) - __apply_Xcode_12_5_M1_post_install_workaround(installer) + # Using ccache when building + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| diff --git a/install-tests/react-native/patches/jsc-Podfile.patch b/install-tests/react-native/patches/jsc-Podfile.patch deleted file mode 100644 index 8bb42c2767..0000000000 --- a/install-tests/react-native/patches/jsc-Podfile.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- app/ios/Podfile -+++ app/ios/Podfile -@@ -15,7 +15,7 @@ - # Hermes is now enabled by default. Disable by setting this flag to false. - # Upcoming versions of React Native may rely on get_default_flags(), but - # we make it explicit here to aid in the React Native upgrade process. -- :hermes_enabled => true, -+ :hermes_enabled => false, - :fabric_enabled => flags[:fabric_enabled], - # Enables Flipper. diff --git a/install-tests/react-native/patches/jsc-build.gradle.patch b/install-tests/react-native/patches/jsc-build.gradle.patch deleted file mode 100644 index 8d261df409..0000000000 --- a/install-tests/react-native/patches/jsc-build.gradle.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- app/android/app/build.gradle -+++ app/android/app/build.gradle -@@ -79,7 +79,7 @@ - */ - - project.ext.react = [ -- enableHermes: true, // clean and rebuild if changing -+ enableHermes: false, // clean and rebuild if changing - ] - - apply from: "../../node_modules/react-native/react.gradle"