Skip to content

fix(0.81, ci): make react-native-macos-init job pass#2915

Open
Saadnajmi wants to merge 13 commits intomicrosoft:0.81-stablefrom
Saadnajmi:fix-macos-platform-config-081
Open

fix(0.81, ci): make react-native-macos-init job pass#2915
Saadnajmi wants to merge 13 commits intomicrosoft:0.81-stablefrom
Saadnajmi:fix-macos-platform-config-081

Conversation

@Saadnajmi
Copy link
Copy Markdown
Collaborator

Summary

  • Fix cli-platform-apple resolution in react-native.config.js to use the same findCommunityPlatformPackage(spec) pattern as ios and android
  • The previous two-step lookup (resolve cli-platform-ios file path → use as search root for cli-platform-apple) passed a file path to require.resolve's paths option, which expects directory paths, causing silent resolution failures

Root cause

When react-native-macos is installed as a dependency (e.g. npm install <path>), the CLI discovers it and loads its react-native.config.js as a dependency config. The apple variable stays null because the file-path-based require.resolve fails silently, so the macos platform is never registered. This causes the bundler to reject --platform macos with:

error: Invalid platform "macos" selected.
Available platforms are: "android", "ios".

Test plan

  • CI "Test react-native-macos init" job should pass

🤖 Generated with Claude Code

The `apple` platform package was being resolved via a two-step lookup:
first resolving `cli-platform-ios` to a file path, then using that file
path as the search root for `cli-platform-apple`. The `require.resolve`
`paths` option expects directory paths, not file paths, causing silent
resolution failures when `react-native-macos` is loaded as a dependency
config (e.g. via `npm install <path>`).

Simplify to use the same `findCommunityPlatformPackage(spec)` pattern
as `ios` and `android`, which defaults to `process.cwd()` as the search
root. Since `cli-platform-apple` is a dependency of `cli-platform-ios`
and gets hoisted by npm, it is directly resolvable from the project root.

Fixes the "Invalid platform macos" error in the init integration test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Saadnajmi Saadnajmi requested a review from a team as a code owner April 10, 2026 22:52
@Saadnajmi Saadnajmi changed the title fix(0.81): resolve macos platform config from cwd instead of ios path fix(0.81, ci): resolve macos platform config from cwd instead of ios path Apr 10, 2026
Saadnajmi and others added 2 commits April 10, 2026 16:19
Two issues prevented the macos platform from being registered when the
test project loads react-native-macos as a dependency:

1. `yarn build` rewrites package.json "exports" from ./src to ./dist
   for publishing. The dist/ files use ESM syntax that requires
   babel-register (only wired up in src/index.js). When the test project
   loads react-native-macos via symlink, require('@react-native/
   community-cli-plugin') resolves to dist/index.js which fails to load,
   silently preventing the macos platform from being registered.

   Fix: restore src exports after yarn build in the CI workflow.

2. The cli-platform-apple resolution used a fragile two-step lookup
   (resolve cli-platform-ios file path, use as search root for
   cli-platform-apple). Simplify to use the same findCommunityPlatform-
   Package(spec) pattern as ios and android, which defaults to cwd.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Saadnajmi Saadnajmi marked this pull request as draft April 11, 2026 00:16
Saadnajmi and others added 7 commits April 10, 2026 17:18
npm install <local-path> creates a symlink, causing Node to follow the
real path back to the monorepo for module resolution. This means
bundle.js loads @react-native/metro-config from the monorepo while
the user's metro.config.js loads it from the test project's
node_modules — two different instances. setFrameworkDefaults() (which
registers the "macos" platform) targets the monorepo's instance, so
the test project never sees it and xcodebuild fails with
"Invalid platform macos".

Using --install-links copies the package files instead, so all
require() calls resolve from a single node_modules tree.

Also removes debug steps that are no longer needed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace npm install --install-links with yarn pack + yarn add.

npm install <local-path> creates a symlink, and --install-links
copies files but without pre-generated codegen headers. Both
diverge from a normal user's install in ways that break the build:

1. Symlinks cause Node module instance duplication (bundle.js loads
   @react-native/metro-config from the monorepo while metro.config.js
   loads it from the test project — setFrameworkDefaults misses).

2. Missing React/FBReactNativeSpec/ headers (generated by prepack.js,
   shipped in published tarballs). Without them the codegen regenerates,
   but the upstream react-native's FBReactNativeSpec processes first,
   creating the directory — then the fork's version is skipped by
   shouldSkipGenerationForFBReactNativeSpec(), leaving headers without
   macOS-specific fields (critical, modal, defaultInputs).

yarn pack runs the prepack script (generating the codegen headers)
and produces a tarball identical to what npm publish would create.
yarn add installs it as a regular package — no symlinks, correct
headers, matching the normal user flow exactly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous commit used yarn --cwd from the testcli directory, but
that invokes the global yarn 1.x which refuses to run due to the
packageManager field. Split into two steps: yarn pack runs from the
monorepo checkout (where Yarn Berry is active), then npm install
installs the tarball in the test project.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
npm pack treats directory entries in "files" as recursive globs, but
yarn pack does not. Use explicit glob patterns (e.g. "scripts/cocoapods/**"
instead of "scripts/cocoapods") so both tools include the full directory
contents.

This is the same fix as facebook#56407.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
yarn pack strips execute permissions from files. Add chmod +x after
npm install to restore permissions on shell scripts that xcodebuild
invokes (react-native-xcode.sh, with-environment.sh, etc.).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
npm pack preserves file permissions from the filesystem, while yarn
pack (Berry) normalizes them and strips execute bits. This removes
the need for the chmod workaround.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Switch back to yarn pack (consistent with publish pipeline) and
restore execute permissions on shell scripts with chmod +x after
install.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Saadnajmi Saadnajmi changed the title fix(0.81, ci): resolve macos platform config from cwd instead of ios path fix(0.81, ci): make react-native-macos-init job pass Apr 11, 2026
The previous glob only matched scripts/*.sh and scripts/xcode/*.sh
but missed scripts/react_native_pods_utils/script_phases.sh. Use
find to recursively chmod all .sh files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Saadnajmi Saadnajmi marked this pull request as ready for review April 11, 2026 04:51
Saadnajmi and others added 2 commits April 10, 2026 21:52
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant