From ddb94a3f78d06334f25588fb7218eefe1a839dd6 Mon Sep 17 00:00:00 2001 From: floydkim Date: Sat, 21 Feb 2026 20:33:01 +0900 Subject: [PATCH 1/5] test(cli-config-apple): add failing test for new architecture flag with forceInstall --- .../cli-config-apple/src/__tests__/pods.test.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/cli-config-apple/src/__tests__/pods.test.ts b/packages/cli-config-apple/src/__tests__/pods.test.ts index 11387bbf6..c79125cb9 100644 --- a/packages/cli-config-apple/src/__tests__/pods.test.ts +++ b/packages/cli-config-apple/src/__tests__/pods.test.ts @@ -103,6 +103,22 @@ describe('resolvePods', () => { expect(installPods).toHaveBeenCalled(); }); + it('passes new architecture flag when force option is set', async () => { + createTempFiles(); + + await resolvePods(DIR, path.join(DIR, 'ios'), {}, 'ios', '', { + forceInstall: true, + newArchEnabled: true, + }); + + expect(installPods).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + newArchEnabled: true, + }), + ); + }); + it('should install pods when there is no cached hash of dependencies', async () => { createTempFiles(); From 54795aaa1f7280125d388906d68be154c7cbcebc Mon Sep 17 00:00:00 2001 From: floydkim Date: Sat, 21 Feb 2026 20:33:06 +0900 Subject: [PATCH 2/5] fix(cli-config-apple): pass new architecture flag during --force-pods pod install --- packages/cli-config-apple/src/tools/pods.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/cli-config-apple/src/tools/pods.ts b/packages/cli-config-apple/src/tools/pods.ts index 8be71a23b..bacbb176e 100644 --- a/packages/cli-config-apple/src/tools/pods.ts +++ b/packages/cli-config-apple/src/tools/pods.ts @@ -94,6 +94,7 @@ async function install( platform: string, root: string, reactNativePath: string, + newArchEnabled?: boolean, ) { const loader = getLoader('Installing CocoaPods...'); try { @@ -105,6 +106,7 @@ async function install( }); await installPods(loader, { skipBundleInstall: !!cachedDependenciesHash, + newArchEnabled, iosFolderPath, }); cacheManager.set(packageJson.name, 'dependencies', currentDependenciesHash); @@ -169,6 +171,7 @@ export default async function resolvePods( platformName, root, reactNativePath, + options?.newArchEnabled, ); } else if ( arePodsInstalled && From d255d180301109a15d1248843b4c9bf064f5c3ed Mon Sep 17 00:00:00 2001 From: floydkim Date: Sun, 22 Feb 2026 20:43:43 +0900 Subject: [PATCH 3/5] test: add failing tests for unknown iOS architecture and pod env propagation --- .../src/__tests__/installPods.test.ts | 70 +++++++++++++++++++ .../tools/__tests__/getArchitecture.test.ts | 41 +++++++++++ 2 files changed, 111 insertions(+) create mode 100644 packages/cli-config-apple/src/__tests__/installPods.test.ts create mode 100644 packages/cli-platform-apple/src/tools/__tests__/getArchitecture.test.ts diff --git a/packages/cli-config-apple/src/__tests__/installPods.test.ts b/packages/cli-config-apple/src/__tests__/installPods.test.ts new file mode 100644 index 000000000..8d095b6ba --- /dev/null +++ b/packages/cli-config-apple/src/__tests__/installPods.test.ts @@ -0,0 +1,70 @@ +import path from 'path'; +import {cleanup, getTempDirectory, writeFiles} from '../../../../jest/helpers'; +import installPods from '../tools/installPods'; +import {execaPod} from '../tools/pods'; + +jest.mock('../tools/pods', () => ({ + execaPod: jest.fn(), +})); + +jest.mock('../tools/runBundleInstall', () => jest.fn()); + +const DIR = getTempDirectory('install_pods_test'); +const IOS_DIR = path.join(DIR, 'ios'); +const originalCwd = process.cwd(); + +beforeEach(() => { + cleanup(DIR); + jest.resetAllMocks(); + process.chdir(originalCwd); + + writeFiles(DIR, { + Gemfile: "source 'https://rubygems.org'", + 'ios/Podfile': 'platform :ios, "13.0"', + }); +}); + +afterEach(() => { + process.chdir(originalCwd); +}); + +describe('installPods', () => { + it('omits RCT_NEW_ARCH_ENABLED when new architecture value is unknown', async () => { + (execaPod as jest.Mock).mockResolvedValue(undefined); + + await installPods(undefined, { + iosFolderPath: IOS_DIR, + skipBundleInstall: true, + }); + + expect(execaPod).toHaveBeenNthCalledWith( + 2, + ['install'], + expect.objectContaining({ + env: expect.not.objectContaining({ + RCT_NEW_ARCH_ENABLED: expect.anything(), + }), + }), + ); + }); + + it('keeps RCT_NEW_ARCH_ENABLED when new architecture value is known', async () => { + (execaPod as jest.Mock).mockResolvedValue(undefined); + + await installPods(undefined, { + iosFolderPath: IOS_DIR, + skipBundleInstall: true, + newArchEnabled: true, + }); + + expect(execaPod).toHaveBeenNthCalledWith( + 2, + ['install'], + expect.objectContaining({ + env: expect.objectContaining({ + RCT_NEW_ARCH_ENABLED: '1', + }), + }), + ); + }); +}); diff --git a/packages/cli-platform-apple/src/tools/__tests__/getArchitecture.test.ts b/packages/cli-platform-apple/src/tools/__tests__/getArchitecture.test.ts new file mode 100644 index 000000000..ec0270190 --- /dev/null +++ b/packages/cli-platform-apple/src/tools/__tests__/getArchitecture.test.ts @@ -0,0 +1,41 @@ +import path from 'path'; +import { + cleanup, + getTempDirectory, + writeFiles, +} from '../../../../../jest/helpers'; +import getArchitecture from '../getArchitecture'; + +const DIR = getTempDirectory('get_architecture_test'); + +beforeEach(() => { + cleanup(DIR); +}); + +describe('getArchitecture', () => { + it('returns undefined when Pods project does not exist', async () => { + const result = await getArchitecture(path.join(DIR, 'ios')); + + expect(result).toBeUndefined(); + }); + + it('returns true when Pods project is configured with new architecture', async () => { + writeFiles(DIR, { + 'ios/Pods/Pods.xcodeproj/project.pbxproj': '-DRCT_NEW_ARCH_ENABLED=1', + }); + + const result = await getArchitecture(path.join(DIR, 'ios')); + + expect(result).toBe(true); + }); + + it('returns false when Pods project does not include new architecture flag', async () => { + writeFiles(DIR, { + 'ios/Pods/Pods.xcodeproj/project.pbxproj': 'SOME_OTHER_FLAG=1', + }); + + const result = await getArchitecture(path.join(DIR, 'ios')); + + expect(result).toBe(false); + }); +}); From aa096f4119231be8023027c233ff40f529c99dae Mon Sep 17 00:00:00 2001 From: floydkim Date: Sun, 22 Feb 2026 20:44:53 +0900 Subject: [PATCH 4/5] fix: avoid forcing legacy pod install when iOS architecture is unknown --- packages/cli-config-apple/src/tools/installPods.ts | 4 +++- packages/cli-doctor/src/commands/info.ts | 2 +- packages/cli-platform-apple/src/tools/getArchitecture.ts | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/cli-config-apple/src/tools/installPods.ts b/packages/cli-config-apple/src/tools/installPods.ts index ec37000e8..727da2549 100644 --- a/packages/cli-config-apple/src/tools/installPods.ts +++ b/packages/cli-config-apple/src/tools/installPods.ts @@ -34,7 +34,9 @@ async function runPodInstall(loader: Ora, options: RunPodInstallOptions) { await execaPod(['install'], { env: { - RCT_NEW_ARCH_ENABLED: options?.newArchEnabled ? '1' : '0', + ...(options?.newArchEnabled !== undefined && { + RCT_NEW_ARCH_ENABLED: options.newArchEnabled ? '1' : '0', + }), // Skip forcing when architecture is unknown (e.g. first pod install) RCT_IGNORE_PODS_DEPRECATION: '1', // From React Native 0.79 onwards, users shouldn't install CocoaPods manually. ...(process.env.USE_THIRD_PARTY_JSC && { USE_THIRD_PARTY_JSC: process.env.USE_THIRD_PARTY_JSC, diff --git a/packages/cli-doctor/src/commands/info.ts b/packages/cli-doctor/src/commands/info.ts index 4947ca813..5a0830cdc 100644 --- a/packages/cli-doctor/src/commands/info.ts +++ b/packages/cli-doctor/src/commands/info.ts @@ -57,7 +57,7 @@ const info = async function getInfo(_argv: Array, ctx: Config) { ctx.project.ios.sourceDir, ); - platforms.iOS.newArchEnabled = isNewArchitecture; + platforms.iOS.newArchEnabled = isNewArchitecture ?? notFound; } catch { platforms.iOS.newArchEnabled = notFound; } diff --git a/packages/cli-platform-apple/src/tools/getArchitecture.ts b/packages/cli-platform-apple/src/tools/getArchitecture.ts index cd5b1c864..820705618 100644 --- a/packages/cli-platform-apple/src/tools/getArchitecture.ts +++ b/packages/cli-platform-apple/src/tools/getArchitecture.ts @@ -9,6 +9,6 @@ export default async function getArchitecture(iosSourceDir: string) { return project.includes('-DRCT_NEW_ARCH_ENABLED=1'); } catch { - return false; + return undefined; } } From c5f2208bca23096159cf0789a64251e2b7909b18 Mon Sep 17 00:00:00 2001 From: floydkim Date: Sun, 22 Feb 2026 22:28:54 +0900 Subject: [PATCH 5/5] docs: update CONTRIBUTING link instructions for cli-config packages --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index af2d83b69..ab818a6ae 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -32,7 +32,7 @@ And then: ```sh cd /my/new/react-native/project/ -yarn link "@react-native-community/cli-platform-ios" "@react-native-community/cli-platform-android" "@react-native-community/cli" "@react-native-community/cli-server-api" "@react-native-community/cli-types" "@react-native-community/cli-tools" "@react-native-community/cli-clean" "@react-native-community/cli-doctor" "@react-native-community/cli-config" "@react-native-community/cli-platform-apple" "@react-native-community/cli-link-assets" +yarn link "@react-native-community/cli-platform-ios" "@react-native-community/cli-platform-android" "@react-native-community/cli" "@react-native-community/cli-server-api" "@react-native-community/cli-types" "@react-native-community/cli-tools" "@react-native-community/cli-clean" "@react-native-community/cli-doctor" "@react-native-community/cli-config" "@react-native-community/cli-config-android" "@react-native-community/cli-platform-apple" "@react-native-community/cli-config-apple" "@react-native-community/cli-link-assets" ``` Once you're done with testing and you'd like to get back to regular setup, run `yarn unlink` instead of `yarn link` from above command. Then `yarn install --force`.