diff --git a/.github/workflows/e2e-v2.yml b/.github/workflows/e2e-v2.yml index 6b9c445ab5..543c0816c7 100644 --- a/.github/workflows/e2e-v2.yml +++ b/.github/workflows/e2e-v2.yml @@ -179,7 +179,7 @@ jobs: strategy: fail-fast: false # keeps matrix running if one fails matrix: - rn-version: ['0.71.19', '0.83.0'] + rn-version: ['0.71.19', '0.84.0-rc.0'] rn-architecture: ['legacy', 'new'] platform: ['android', 'ios'] build-type: ['production'] @@ -191,16 +191,16 @@ jobs: rn-version: '0.71.19' xcode-version: '16.4' runs-on: macos-15 - # Use Xcode 26 for newer RN versions (0.83.0) + # Use Xcode 26 for newer RN versions (0.84.0-rc.0) - platform: ios - rn-version: '0.83.0' + rn-version: '0.84.0-rc.0' xcode-version: '26.1.1' runs-on: macos-26 - platform: android runs-on: ubuntu-latest exclude: # exclude JSC for new RN versions (keeping the matrix manageable) - - rn-version: '0.83.0' + - rn-version: '0.84.0-rc.0' engine: 'jsc' # exclude all rn versions lower than 0.80.0 for new architecture - rn-version: '0.71.19' @@ -314,7 +314,7 @@ jobs: strategy: fail-fast: false # keeps matrix running if one fails matrix: - rn-version: ['0.83.0'] + rn-version: ['0.84.0-rc.0'] rn-architecture: ['legacy', 'new'] platform: ['android', 'ios'] build-type: ['production'] @@ -322,7 +322,7 @@ jobs: engine: ['hermes'] include: - platform: ios - rn-version: '0.83.0' + rn-version: '0.84.0-rc.0' runs-on: macos-26 - platform: android runs-on: ubuntu-latest diff --git a/dev-packages/e2e-tests/cli.mjs b/dev-packages/e2e-tests/cli.mjs index c3ee22f3f7..fded8479b3 100755 --- a/dev-packages/e2e-tests/cli.mjs +++ b/dev-packages/e2e-tests/cli.mjs @@ -156,7 +156,7 @@ if (actions.includes('create')) { env: Object.assign(env, { YARN_ENABLE_IMMUTABLE_INSTALLS: false }), }); - // Patch react-native-launch-arguments for Gradle 9+ compatibility + // Patch react-native-launch-arguments for Gradle 9+ compatibility (Android) and React Native 0.84+ compatibility (iOS) execSync(`${patchScriptsDir}/rn.patch.launch-arguments.js --app-dir .`, { stdio: 'inherit', cwd: appDir, @@ -189,6 +189,14 @@ if (actions.includes('create')) { env: env, }); + // Clean Pods to ensure CocoaPods reads the patched podspec + if (fs.existsSync(`${appDir}/ios/Pods`)) { + fs.rmSync(`${appDir}/ios/Pods`, { recursive: true }); + } + if (fs.existsSync(`${appDir}/ios/Podfile.lock`)) { + fs.rmSync(`${appDir}/ios/Podfile.lock`); + } + if (fs.existsSync(`${appDir}/Gemfile`)) { execSync(`bundle install`, { stdio: 'inherit', cwd: appDir, env: env }); execSync('bundle exec pod install --repo-update', { stdio: 'inherit', cwd: `${appDir}/ios`, env: env }); diff --git a/dev-packages/e2e-tests/patch-scripts/rn.patch.launch-arguments.js b/dev-packages/e2e-tests/patch-scripts/rn.patch.launch-arguments.js index 8c3a9b5648..1d41201539 100755 --- a/dev-packages/e2e-tests/patch-scripts/rn.patch.launch-arguments.js +++ b/dev-packages/e2e-tests/patch-scripts/rn.patch.launch-arguments.js @@ -25,22 +25,66 @@ debug.log('Patching react-native-launch-arguments build.gradle', buildGradlePath if (!fs.existsSync(buildGradlePath)) { debug.log('build.gradle not found, skipping patch'); - return; +} else { + const buildGradle = fs.readFileSync(buildGradlePath, 'utf8'); + + // Replace destinationDir with destinationDirectory.get() for Gradle 9+ compatibility + const isPatched = buildGradle.includes('destinationDirectory.get()'); + if (!isPatched) { + const patched = buildGradle.replace( + /\.destinationDir\b/g, + '.destinationDirectory.get()' + ); + + fs.writeFileSync(buildGradlePath, patched); + debug.log('Patched react-native-launch-arguments build.gradle successfully!'); + } else { + debug.log('react-native-launch-arguments build.gradle is already patched!'); + } } -const buildGradle = fs.readFileSync(buildGradlePath, 'utf8'); +// Patch iOS podspec for React Native 0.71+ compatibility +// Replace 'React' with 'React-Core' to fix RCTRegisterModule undefined symbol error in RN 0.84+ with dynamic frameworks +const podspecPath = path.join( + args['app-dir'], + 'node_modules', + 'react-native-launch-arguments', + 'react-native-launch-arguments.podspec' +); + +debug.log('Patching react-native-launch-arguments podspec', podspecPath); + +if (fs.existsSync(podspecPath)) { + const podspec = fs.readFileSync(podspecPath, 'utf8'); + debug.log('Found podspec, checking for React dependency...'); + + const isPatched = podspec.includes("s.dependency 'React-Core'") || podspec.includes('s.dependency "React-Core"'); + const hasReactDep = /s\.dependency\s+['"]React['"]/.test(podspec); + const hasReactCoreDep = /s\.dependency\s+['"]React\/Core['"]/.test(podspec); + + debug.log(`Podspec status: isPatched=${isPatched}, hasReactDep=${hasReactDep}, hasReactCoreDep=${hasReactCoreDep}`); + + if (!isPatched && (hasReactDep || hasReactCoreDep)) { + let patched = podspec; + + if (hasReactDep) { + debug.log("Replacing s.dependency 'React' with s.dependency 'React-Core'"); + patched = patched.replace(/s\.dependency\s+['"]React['"]/g, "s.dependency 'React-Core'"); + } -// Replace destinationDir with destinationDirectory.get() for Gradle 9+ compatibility -const isPatched = buildGradle.includes('destinationDirectory.get()'); -if (!isPatched) { - const patched = buildGradle.replace( - /\.destinationDir\b/g, - '.destinationDirectory.get()' - ); + if (hasReactCoreDep) { + debug.log("Replacing s.dependency 'React/Core' with s.dependency 'React-Core'"); + patched = patched.replace(/s\.dependency\s+['"]React\/Core['"]/g, "s.dependency 'React-Core'"); + } - fs.writeFileSync(buildGradlePath, patched); - debug.log('Patched react-native-launch-arguments build.gradle successfully!'); + fs.writeFileSync(podspecPath, patched); + debug.log('Patched react-native-launch-arguments podspec successfully!'); + } else if (isPatched) { + debug.log('react-native-launch-arguments podspec is already patched!'); + } else { + debug.log('Podspec does not contain React dependency - may use install_modules_dependencies'); + } } else { - debug.log('react-native-launch-arguments build.gradle is already patched!'); + debug.log('podspec not found, skipping iOS patch'); }