Skip to content

Commit cd5f27f

Browse files
antonisclaude
andauthored
chore(deps): Bump E2E tests to 0.84.0 (#5492)
* chore(deps): Bump E2E tests to 0.83.1 * Bump to 0.84.0-rc.0 * Fix Build RN 0.84.0-rc.0 legacy hermes ios production dynamic * Iterate on the fix * Update React Native version to 0.84.0-rc.1 * Bump to 0.84.0-rc.3 * Bump to 0.84.0-rc.4 * Update React Native version from rc.4 to rc.5 * Bump to 0.84.0 * fix(e2e): Use install_modules_dependencies for react-native-launch-arguments Enhances the patch script to use install_modules_dependencies() instead of hardcoded React/React-Core dependencies. This is the modern approach for React Native 0.60+ that properly handles all framework configurations (static, dynamic, etc.) and automatically resolves the correct React Native dependencies. This should fix the "Undefined symbols: _RCTRegisterModule" error when building RN 0.84.0 with dynamic frameworks on iOS. The patch now uses the same defensive pattern as RNSentry.podspec, with a fallback to React-Core for older RN versions that don't have install_modules_dependencies defined. Tested locally and verified: - Patch successfully replaces s.dependency "React" - Generated Ruby syntax is valid - Idempotent (safe to run multiple times) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent d4d1a1d commit cd5f27f

File tree

3 files changed

+83
-18
lines changed

3 files changed

+83
-18
lines changed

.github/workflows/e2e-v2.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ jobs:
189189
strategy:
190190
fail-fast: false # keeps matrix running if one fails
191191
matrix:
192-
rn-version: ['0.71.19', '0.83.0']
192+
rn-version: ['0.71.19', '0.84.0']
193193
rn-architecture: ['legacy', 'new']
194194
platform: ['android', 'ios']
195195
build-type: ['production']
@@ -202,13 +202,13 @@ jobs:
202202
runs-on: ["ghcr.io/cirruslabs/macos-sequoia-xcode:16.4", "runner_group_id:12"]
203203
# Use Xcode 26 for newer RN versions (0.83.0)
204204
- platform: ios
205-
rn-version: '0.83.0'
205+
rn-version: '0.84.0'
206206
runs-on: ["ghcr.io/cirruslabs/macos-tahoe-xcode:26.2.0", "runner_group_id:12"]
207207
- platform: android
208208
runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:22.04", "runner_group_id:12"]
209209
exclude:
210210
# exclude JSC for new RN versions (keeping the matrix manageable)
211-
- rn-version: '0.83.0'
211+
- rn-version: '0.84.0'
212212
engine: 'jsc'
213213
# exclude all rn versions lower than 0.80.0 for new architecture
214214
- rn-version: '0.71.19'
@@ -323,15 +323,15 @@ jobs:
323323
strategy:
324324
fail-fast: false # keeps matrix running if one fails
325325
matrix:
326-
rn-version: ['0.83.0']
326+
rn-version: ['0.84.0']
327327
rn-architecture: ['legacy', 'new']
328328
platform: ['android', 'ios']
329329
build-type: ['production']
330330
ios-use-frameworks: ['no'] # test only no frameworks
331331
engine: ['hermes']
332332
include:
333333
- platform: ios
334-
rn-version: '0.83.0'
334+
rn-version: '0.84.0'
335335
runs-on: macos-26
336336
- platform: android
337337
runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:22.04", "runner_group_id:12"]

dev-packages/e2e-tests/cli.mjs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ if (actions.includes('create')) {
156156
env: Object.assign(env, { YARN_ENABLE_IMMUTABLE_INSTALLS: false }),
157157
});
158158

159-
// Patch react-native-launch-arguments for Gradle 9+ compatibility
159+
// Patch react-native-launch-arguments for Gradle 9+ compatibility (Android) and React Native 0.84+ compatibility (iOS)
160160
execSync(`${patchScriptsDir}/rn.patch.launch-arguments.js --app-dir .`, {
161161
stdio: 'inherit',
162162
cwd: appDir,
@@ -189,6 +189,14 @@ if (actions.includes('create')) {
189189
env: env,
190190
});
191191

192+
// Clean Pods to ensure CocoaPods reads the patched podspec
193+
if (fs.existsSync(`${appDir}/ios/Pods`)) {
194+
fs.rmSync(`${appDir}/ios/Pods`, { recursive: true });
195+
}
196+
if (fs.existsSync(`${appDir}/ios/Podfile.lock`)) {
197+
fs.rmSync(`${appDir}/ios/Podfile.lock`);
198+
}
199+
192200
if (fs.existsSync(`${appDir}/Gemfile`)) {
193201
execSync(`bundle install`, { stdio: 'inherit', cwd: appDir, env: env });
194202
execSync('bundle exec pod install --repo-update', { stdio: 'inherit', cwd: `${appDir}/ios`, env: env });

dev-packages/e2e-tests/patch-scripts/rn.patch.launch-arguments.js

Lines changed: 69 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,79 @@ debug.log('Patching react-native-launch-arguments build.gradle', buildGradlePath
2525

2626
if (!fs.existsSync(buildGradlePath)) {
2727
debug.log('build.gradle not found, skipping patch');
28-
return;
28+
} else {
29+
const buildGradle = fs.readFileSync(buildGradlePath, 'utf8');
30+
31+
// Replace destinationDir with destinationDirectory.get() for Gradle 9+ compatibility
32+
const isPatched = buildGradle.includes('destinationDirectory.get()');
33+
if (!isPatched) {
34+
const patched = buildGradle.replace(
35+
/\.destinationDir\b/g,
36+
'.destinationDirectory.get()'
37+
);
38+
39+
fs.writeFileSync(buildGradlePath, patched);
40+
debug.log('Patched react-native-launch-arguments build.gradle successfully!');
41+
} else {
42+
debug.log('react-native-launch-arguments build.gradle is already patched!');
43+
}
2944
}
3045

31-
const buildGradle = fs.readFileSync(buildGradlePath, 'utf8');
46+
// Patch iOS podspec for React Native 0.71+ compatibility
47+
// Replace 'React' with install_modules_dependencies() to fix RCTRegisterModule undefined symbol error in RN 0.84+ with dynamic frameworks
48+
const podspecPath = path.join(
49+
args['app-dir'],
50+
'node_modules',
51+
'react-native-launch-arguments',
52+
'react-native-launch-arguments.podspec'
53+
);
54+
55+
debug.log('Patching react-native-launch-arguments podspec', podspecPath);
56+
57+
if (fs.existsSync(podspecPath)) {
58+
const podspec = fs.readFileSync(podspecPath, 'utf8');
59+
debug.log('Found podspec, checking for React dependency...');
60+
61+
// Check if already patched with install_modules_dependencies
62+
const isPatched = podspec.includes('install_modules_dependencies');
63+
const hasReactDep = /s\.dependency\s+['"]React['"]/.test(podspec);
64+
const hasReactCoreDep = /s\.dependency\s+['"]React\/Core['"]/.test(podspec);
65+
const hasReactCoreDepOnly = podspec.includes("s.dependency 'React-Core'") || podspec.includes('s.dependency "React-Core"');
66+
67+
debug.log(`Podspec status: isPatched=${isPatched}, hasReactDep=${hasReactDep}, hasReactCoreDep=${hasReactCoreDep}, hasReactCoreDepOnly=${hasReactCoreDepOnly}`);
68+
69+
if (!isPatched && (hasReactDep || hasReactCoreDep || hasReactCoreDepOnly)) {
70+
let patched = podspec;
71+
72+
// Replace any React dependency with install_modules_dependencies(s)
73+
// This is the modern approach that works with all framework configurations (static, dynamic, etc.)
74+
// and automatically includes the correct React Native dependencies
75+
const installModulesDepsBlock = `
76+
if defined? install_modules_dependencies
77+
install_modules_dependencies(s)
78+
else
79+
s.dependency "React-Core"
80+
end`;
3281

33-
// Replace destinationDir with destinationDirectory.get() for Gradle 9+ compatibility
34-
const isPatched = buildGradle.includes('destinationDirectory.get()');
35-
if (!isPatched) {
36-
const patched = buildGradle.replace(
37-
/\.destinationDir\b/g,
38-
'.destinationDirectory.get()'
39-
);
82+
if (hasReactDep) {
83+
debug.log("Replacing s.dependency 'React' with install_modules_dependencies(s)");
84+
patched = patched.replace(/\s+s\.dependency\s+['"]React['"]\s*\n/g, installModulesDepsBlock + '\n');
85+
} else if (hasReactCoreDep) {
86+
debug.log("Replacing s.dependency 'React/Core' with install_modules_dependencies(s)");
87+
patched = patched.replace(/\s+s\.dependency\s+['"]React\/Core['"]\s*\n/g, installModulesDepsBlock + '\n');
88+
} else if (hasReactCoreDepOnly) {
89+
debug.log("Replacing s.dependency 'React-Core' with install_modules_dependencies(s)");
90+
patched = patched.replace(/\s+s\.dependency\s+['"]React-Core['"]\s*\n/g, installModulesDepsBlock + '\n');
91+
}
4092

41-
fs.writeFileSync(buildGradlePath, patched);
42-
debug.log('Patched react-native-launch-arguments build.gradle successfully!');
93+
fs.writeFileSync(podspecPath, patched);
94+
debug.log('Patched react-native-launch-arguments podspec successfully!');
95+
} else if (isPatched) {
96+
debug.log('react-native-launch-arguments podspec is already patched!');
97+
} else {
98+
debug.log('Podspec does not contain React dependency - may already use install_modules_dependencies');
99+
}
43100
} else {
44-
debug.log('react-native-launch-arguments build.gradle is already patched!');
101+
debug.log('podspec not found, skipping iOS patch');
45102
}
46103

0 commit comments

Comments
 (0)