Skip to content

Commit 48b1ff7

Browse files
committed
Upgrade ERN to support RN 0.81
1 parent 94d2faf commit 48b1ff7

38 files changed

Lines changed: 854 additions & 38 deletions

azure/templates/system-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
steps:
22
- task: NodeTool@0
33
inputs:
4-
versionSpec: '18.x'
4+
versionSpec: '20.x'
55
displayName: 'Install Node.js'
66
- script: |
77
git config --global user.email "electrodenative@gmail.com"

azure/templates/unit-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
steps:
22
- task: NodeTool@0
33
inputs:
4-
versionSpec: '18.x'
4+
versionSpec: '20.x'
55
displayName: 'Install Node.js'
66
- script: |
77
yarn --frozen-lockfile

ern-composite-gen/src/addRNDepToPjson.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,22 @@ export async function addRNDepToPjson(dir: string, version: string) {
77

88
// For React Native 0.77+, also add required dependencies
99
// This is required by the new Metro config format and CLI
10-
if (semver.gte(version, '0.77.0')) {
10+
if (semver.gte(version, '0.81.0')) {
11+
compositePackageJson.dependencies['@react-native/metro-config'] = version;
12+
compositePackageJson.dependencies['@react-native/babel-preset'] = version;
13+
// RN 0.81+ uses @react-native/community-cli-plugin (internal to RN monorepo)
14+
compositePackageJson.dependencies[
15+
'@react-native/community-cli-plugin'
16+
] = version;
17+
// Add CLI packages to ensure android and ios platforms are available
18+
compositePackageJson.dependencies['@react-native-community/cli'] = '15.1.3';
19+
compositePackageJson.dependencies[
20+
'@react-native-community/cli-platform-android'
21+
] = '15.1.3';
22+
compositePackageJson.dependencies[
23+
'@react-native-community/cli-platform-ios'
24+
] = '15.1.3';
25+
} else if (semver.gte(version, '0.77.0')) {
1126
compositePackageJson.dependencies['@react-native/metro-config'] = version;
1227
compositePackageJson.dependencies['@react-native/babel-preset'] = version;
1328
// Add CLI packages to ensure android and ios platforms are available
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip
44
networkTimeout=10000
55
zipStoreBase=GRADLE_USER_HOME
66
zipStorePath=wrapper/dists

ern-core/src/ReactNativeCli.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ export default class ReactNativeCli {
8989
}
9090
const initCmd = `init ${projectName} ${options.join(' ')}`;
9191

92-
if (semver.gte(rnVersion, '0.77.0')) {
92+
if (semver.gte(rnVersion, '0.81.0')) {
93+
return execp(`npx @react-native-community/cli@15.1.3 ${initCmd}`);
94+
} else if (semver.gte(rnVersion, '0.77.0')) {
9395
return execp(`npx @react-native-community/cli@15.0.1 ${initCmd}`);
9496
} else if (semver.gte(rnVersion, '0.60.0')) {
9597
return execp(

ern-core/src/android.ts

Lines changed: 69 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@ export const DEFAULT_ANDROID_GRADLE_PLUGIN_VERSION = '7.0.4';
1616
export const DEFAULT_RN_GRADLE_PLUGIN_VERSION = '0.0.6';
1717
export const DEFAULT_ANDROIDX_APPCOMPACT_VERSION = '1.1.0';
1818
export const DEFAULT_ANDROIDX_LIFECYCLE_EXTENSIONS_VERSION = '2.1.0';
19-
export const DEFAULT_BUILD_TOOLS_VERSION = '35.0.0';
20-
export const DEFAULT_COMPILE_SDK_VERSION = '35';
21-
export const DEFAULT_GRADLE_DISTRIBUTION_VERSION = '8.11.1';
19+
export const DEFAULT_BUILD_TOOLS_VERSION = '36.0.0';
20+
export const DEFAULT_COMPILE_SDK_VERSION = '36';
21+
export const DEFAULT_GRADLE_DISTRIBUTION_VERSION = '8.14.3';
2222
export const DEFAULT_JSC_VARIANT = 'android-jsc';
23-
export const DEFAULT_KOTLIN_VERSION = '2.0.21';
23+
export const DEFAULT_KOTLIN_VERSION = '2.1.20';
2424
export const DEFAULT_MIN_SDK_VERSION_PRE_RN64 = '19';
2525
export const DEFAULT_MIN_SDK_VERSION_POST_RN64 = '21';
2626
export const DEFAULT_MIN_SDK_VERSION_POST_RN77 = '24';
2727
export const DEFAULT_SUPPORT_LIBRARY_VERSION = '28.0.0';
28-
export const DEFAULT_TARGET_SDK_VERSION = '35';
28+
export const DEFAULT_TARGET_SDK_VERSION = '36';
2929
export const DEFAULT_SOURCE_COMPATIBILITY = 'VERSION_17';
3030
export const DEFAULT_TARGET_COMPATIBILITY = 'VERSION_17';
3131
const ANDROID_DEVICE_INFO = `
@@ -54,16 +54,16 @@ export function resolveAndroidVersions({
5454
androidGradlePlugin,
5555
androidxAppcompactVersion = DEFAULT_ANDROIDX_APPCOMPACT_VERSION,
5656
androidxLifecycleExtrnsionsVersion = DEFAULT_ANDROIDX_LIFECYCLE_EXTENSIONS_VERSION,
57-
buildToolsVersion = DEFAULT_BUILD_TOOLS_VERSION,
58-
compileSdkVersion = DEFAULT_COMPILE_SDK_VERSION,
59-
gradleDistributionVersion = DEFAULT_GRADLE_DISTRIBUTION_VERSION,
60-
kotlinVersion = DEFAULT_KOTLIN_VERSION,
57+
buildToolsVersion,
58+
compileSdkVersion,
59+
gradleDistributionVersion,
60+
kotlinVersion,
6161
minSdkVersion,
6262
reactNativeAarVersion,
6363
sourceCompatibility = DEFAULT_SOURCE_COMPATIBILITY,
6464
supportLibraryVersion = DEFAULT_SUPPORT_LIBRARY_VERSION,
6565
targetCompatibility = DEFAULT_TARGET_COMPATIBILITY,
66-
targetSdkVersion = DEFAULT_TARGET_SDK_VERSION,
66+
targetSdkVersion,
6767
reactNativeVersion,
6868
}: {
6969
rnGradlePlugin?: string;
@@ -95,22 +95,33 @@ export function resolveAndroidVersions({
9595
rnGradlePlugin ?? getReactNativeGradlePluginVersion(reactNativeVersion!);
9696
const resolvedAndroidGradlePlugin =
9797
androidGradlePlugin ?? getGradlePluginVersion(reactNativeVersion!);
98+
const resolvedBuildToolsVersion =
99+
buildToolsVersion ?? getDefaultBuildToolsVersion(reactNativeVersion!);
100+
const resolvedCompileSdkVersion =
101+
compileSdkVersion ?? getDefaultCompileSdkVersion(reactNativeVersion!);
102+
const resolvedGradleDistributionVersion =
103+
gradleDistributionVersion ??
104+
getDefaultGradleDistributionVersion(reactNativeVersion!);
105+
const resolvedKotlinVersion =
106+
kotlinVersion ?? getDefaultKotlinVersion(reactNativeVersion!);
107+
const resolvedTargetSdkVersion =
108+
targetSdkVersion ?? getDefaultTargetSdkVersion(reactNativeVersion!);
98109

99110
return {
100111
rnGradlePlugin: resolvedRNGradlePlugin,
101112
androidGradlePlugin: resolvedAndroidGradlePlugin,
102113
androidxAppcompactVersion,
103114
androidxLifecycleExtrnsionsVersion,
104-
buildToolsVersion,
105-
compileSdkVersion,
106-
gradleDistributionVersion,
107-
kotlinVersion,
115+
buildToolsVersion: resolvedBuildToolsVersion,
116+
compileSdkVersion: resolvedCompileSdkVersion,
117+
gradleDistributionVersion: resolvedGradleDistributionVersion,
118+
kotlinVersion: resolvedKotlinVersion,
108119
minSdkVersion: resolvedMinSdkVersion,
109120
reactNativeAarVersion,
110121
sourceCompatibility,
111122
supportLibraryVersion,
112123
targetCompatibility,
113-
targetSdkVersion,
124+
targetSdkVersion: resolvedTargetSdkVersion,
114125
};
115126
}
116127

@@ -470,9 +481,48 @@ export function androidEmulatorPath(): string {
470481
return 'emulator';
471482
}
472483

484+
function getDefaultBuildToolsVersion(reactNativeVersion: string): string {
485+
if (semver.gte(reactNativeVersion, '0.81.0')) {
486+
return '36.0.0';
487+
}
488+
return '35.0.0';
489+
}
490+
491+
function getDefaultCompileSdkVersion(reactNativeVersion: string): string {
492+
if (semver.gte(reactNativeVersion, '0.81.0')) {
493+
return '36';
494+
}
495+
return '35';
496+
}
497+
498+
function getDefaultGradleDistributionVersion(
499+
reactNativeVersion: string,
500+
): string {
501+
if (semver.gte(reactNativeVersion, '0.81.0')) {
502+
return '8.14.3';
503+
}
504+
return '8.11.1';
505+
}
506+
507+
function getDefaultKotlinVersion(reactNativeVersion: string): string {
508+
if (semver.gte(reactNativeVersion, '0.81.0')) {
509+
return '2.1.20';
510+
}
511+
return '2.0.21';
512+
}
513+
514+
function getDefaultTargetSdkVersion(reactNativeVersion: string): string {
515+
if (semver.gte(reactNativeVersion, '0.81.0')) {
516+
return '36';
517+
}
518+
return '35';
519+
}
520+
473521
// ERN Android plugins supports backward compatibility until react native version 68.
474522
function getGradlePluginVersion(reactNativeVersion: string): string | never {
475-
if (semver.gte(reactNativeVersion, '0.77.0')) {
523+
if (semver.gte(reactNativeVersion, '0.81.0')) {
524+
return '8.11.0';
525+
} else if (semver.gte(reactNativeVersion, '0.77.0')) {
476526
return '8.7.2';
477527
} else if (semver.gte(reactNativeVersion, '0.72.0')) {
478528
return '7.4.2';
@@ -490,7 +540,9 @@ function getGradlePluginVersion(reactNativeVersion: string): string | never {
490540
function getReactNativeGradlePluginVersion(
491541
reactNativeVersion: string,
492542
): string | never {
493-
if (semver.gte(reactNativeVersion, '0.77.0')) {
543+
if (semver.gte(reactNativeVersion, '0.81.0')) {
544+
return '0.81.5';
545+
} else if (semver.gte(reactNativeVersion, '0.77.0')) {
494546
return '0.77.2';
495547
} else if (semver.gte(reactNativeVersion, '0.72.0')) {
496548
return '0.72.11';

ern-core/src/injectReactNativeVersionKeysInObject.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export function injectReactNativeVersionKeysInObject(
1111
RN_VERSION_GTE_60_1: semver.gte(reactNativeVersion, '0.60.1'),
1212
RN_VERSION_GTE_61: semver.gte(reactNativeVersion, '0.61.0'),
1313
RN_VERSION_GTE_77: semver.gte(reactNativeVersion, '0.77.0'),
14+
RN_VERSION_GTE_81: semver.gte(reactNativeVersion, '0.81.0'),
1415
RN_VERSION_LT_54: semver.lt(reactNativeVersion, '0.54.0'),
1516
RN_VERSION_LT_58: semver.lt(reactNativeVersion, '0.58.0-rc.2'),
1617
RN_VERSION_LT_59: semver.lt(reactNativeVersion, '0.59.0'),

ern-core/src/iosUtil.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,9 @@ export const getDefaultIosDeploymentTarget = (rnVersion: string): string => {
582582
export const getReactNativeCodegenVersion = (
583583
rnVersion: string,
584584
): string | null => {
585-
if (semver.gte(rnVersion, '0.77.0')) {
585+
if (semver.gte(rnVersion, '0.81.0')) {
586+
return '0.81.5';
587+
} else if (semver.gte(rnVersion, '0.77.0')) {
586588
return '0.77.2';
587589
} else if (semver.gte(rnVersion, '0.72.0')) {
588590
return '0.72.8';

ern-core/test/android-test.ts

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -209,26 +209,47 @@ describe('android.js', () => {
209209
});
210210

211211
describe('resolveAndroidVersions', () => {
212+
it('should return all default versions if no versions are provided [>= RN 0.81.0]', () => {
213+
const versions = android.resolveAndroidVersions({
214+
reactNativeVersion: '0.81.0',
215+
});
216+
expect(versions).deep.equal({
217+
androidGradlePlugin: '8.11.0',
218+
rnGradlePlugin: '0.81.5',
219+
androidxAppcompactVersion: '1.1.0',
220+
androidxLifecycleExtrnsionsVersion: '2.1.0',
221+
buildToolsVersion: '36.0.0',
222+
compileSdkVersion: '36',
223+
gradleDistributionVersion: '8.14.3',
224+
kotlinVersion: '2.1.20',
225+
minSdkVersion: '24',
226+
reactNativeAarVersion: '0.81.0',
227+
sourceCompatibility: 'VERSION_17',
228+
supportLibraryVersion: '28.0.0',
229+
targetCompatibility: 'VERSION_17',
230+
targetSdkVersion: '36',
231+
});
232+
});
233+
212234
it('should return all default versions if no versions are provided [>= RN 0.77.0]', () => {
213235
const versions = android.resolveAndroidVersions({
214236
reactNativeVersion: '0.77.0',
215237
});
216238
expect(versions).deep.equal({
217239
androidGradlePlugin: '8.7.2',
218240
rnGradlePlugin: '0.77.2',
219-
androidxAppcompactVersion: android.DEFAULT_ANDROIDX_APPCOMPACT_VERSION,
220-
androidxLifecycleExtrnsionsVersion:
221-
android.DEFAULT_ANDROIDX_LIFECYCLE_EXTENSIONS_VERSION,
222-
buildToolsVersion: android.DEFAULT_BUILD_TOOLS_VERSION,
223-
compileSdkVersion: android.DEFAULT_COMPILE_SDK_VERSION,
224-
gradleDistributionVersion: android.DEFAULT_GRADLE_DISTRIBUTION_VERSION,
225-
kotlinVersion: android.DEFAULT_KOTLIN_VERSION,
226-
minSdkVersion: android.DEFAULT_MIN_SDK_VERSION_POST_RN77,
241+
androidxAppcompactVersion: '1.1.0',
242+
androidxLifecycleExtrnsionsVersion: '2.1.0',
243+
buildToolsVersion: '35.0.0',
244+
compileSdkVersion: '35',
245+
gradleDistributionVersion: '8.11.1',
246+
kotlinVersion: '2.0.21',
247+
minSdkVersion: '24',
227248
reactNativeAarVersion: '0.77.0',
228-
sourceCompatibility: android.DEFAULT_SOURCE_COMPATIBILITY,
229-
supportLibraryVersion: android.DEFAULT_SUPPORT_LIBRARY_VERSION,
230-
targetCompatibility: android.DEFAULT_TARGET_COMPATIBILITY,
231-
targetSdkVersion: android.DEFAULT_TARGET_SDK_VERSION,
249+
sourceCompatibility: 'VERSION_17',
250+
supportLibraryVersion: '28.0.0',
251+
targetCompatibility: 'VERSION_17',
252+
targetSdkVersion: '35',
232253
});
233254
});
234255

@@ -241,7 +262,7 @@ describe('android.js', () => {
241262
rnGradlePlugin: '0.72.11',
242263
androidxAppcompactVersion: android.DEFAULT_ANDROIDX_APPCOMPACT_VERSION,
243264
androidxLifecycleExtrnsionsVersion:
244-
android.DEFAULT_ANDROIDX_LIFECYCLE_EXTENSIONS_VERSION,
265+
android.DEFAULT_ANDROIDX_LIFECYCLE_EXTENSIONS_VERSION,
245266
buildToolsVersion: android.DEFAULT_BUILD_TOOLS_VERSION,
246267
compileSdkVersion: android.DEFAULT_COMPILE_SDK_VERSION,
247268
gradleDistributionVersion: android.DEFAULT_GRADLE_DISTRIBUTION_VERSION,
@@ -264,7 +285,7 @@ describe('android.js', () => {
264285
rnGradlePlugin: android.DEFAULT_RN_GRADLE_PLUGIN_VERSION,
265286
androidxAppcompactVersion: android.DEFAULT_ANDROIDX_APPCOMPACT_VERSION,
266287
androidxLifecycleExtrnsionsVersion:
267-
android.DEFAULT_ANDROIDX_LIFECYCLE_EXTENSIONS_VERSION,
288+
android.DEFAULT_ANDROIDX_LIFECYCLE_EXTENSIONS_VERSION,
268289
buildToolsVersion: android.DEFAULT_BUILD_TOOLS_VERSION,
269290
compileSdkVersion: android.DEFAULT_COMPILE_SDK_VERSION,
270291
gradleDistributionVersion: android.DEFAULT_GRADLE_DISTRIBUTION_VERSION,
@@ -287,7 +308,7 @@ describe('android.js', () => {
287308
rnGradlePlugin: android.DEFAULT_RN_GRADLE_PLUGIN_VERSION,
288309
androidxAppcompactVersion: android.DEFAULT_ANDROIDX_APPCOMPACT_VERSION,
289310
androidxLifecycleExtrnsionsVersion:
290-
android.DEFAULT_ANDROIDX_LIFECYCLE_EXTENSIONS_VERSION,
311+
android.DEFAULT_ANDROIDX_LIFECYCLE_EXTENSIONS_VERSION,
291312
buildToolsVersion: android.DEFAULT_BUILD_TOOLS_VERSION,
292313
compileSdkVersion: android.DEFAULT_COMPILE_SDK_VERSION,
293314
gradleDistributionVersion: android.DEFAULT_GRADLE_DISTRIBUTION_VERSION,

ern-runner-gen-android/test/AndroidRunnerGenerator-test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,44 @@ describe('Test AndroidRunnerGenerator for RN version 0.77.x', () => {
127127
);
128128
});
129129
});
130+
131+
describe('Test AndroidRunnerGenerator for RN version 0.81.x', () => {
132+
const fixtureRunnerPath = path.join(
133+
__dirname,
134+
'fixtures',
135+
'simple-android-runner-rn-81',
136+
);
137+
const generatedRunnerPath = tmp.dirSync({ unsafeCleanup: true }).name;
138+
process.chdir(generatedRunnerPath);
139+
140+
const generatorConfig: RunnerGeneratorConfig = {
141+
extra: {
142+
androidConfig: {
143+
artifactId: 'runner-ern-container-dummy',
144+
groupId: 'com.walmartlabs.ern',
145+
packageFilePath: 'com/walmartlabs/ern/dummy',
146+
packageName: 'com.walmartlabs.ern.dummy',
147+
},
148+
},
149+
mainMiniAppName: 'dummy',
150+
outDir: generatedRunnerPath,
151+
reactNativeVersion: '0.81.0',
152+
targetPlatform: 'android',
153+
};
154+
155+
it('should generate simple-android-runner fixture given same configuration', async () => {
156+
await new AndroidRunnerGenerator().generate(generatorConfig);
157+
assert(
158+
sameDirContent(fixtureRunnerPath, generatedRunnerPath),
159+
'Generated Android Runner project differs from simple-android-runner fixture',
160+
);
161+
});
162+
163+
it('should re-generate configuration of simple-android-runner fixture given same configuration', async () => {
164+
await new AndroidRunnerGenerator().regenerateRunnerConfig(generatorConfig);
165+
assert(
166+
sameDirContent(fixtureRunnerPath, generatedRunnerPath),
167+
'Generated Android Runner project differs from simple-android-runner fixture',
168+
);
169+
});
170+
});

0 commit comments

Comments
 (0)