Skip to content

Commit 64c9663

Browse files
IsaacIsraelmeta-codesync[bot]
authored andcommitted
fix(ios): make Podfile.lock SPEC CHECKSUMS deterministic across machines (#56994)
Summary: Two sources of non-determinism cause `Podfile.lock` SPEC CHECKSUMS to differ between machines, breaking `pod install --deployment` in CI and creating unnecessary churn in PRs. ### Fix 1: Sort `Dir.glob` results in `Yoga.podspec` `Dir.glob` returns files in filesystem-dependent order (varies across macOS APFS volumes, case sensitivity settings, and Linux ext4/xfs). Since CocoaPods evaluates the podspec at install time, the resulting array order differs between machines, producing different spec checksums. ```ruby # Before spec.private_header_files = Dir.glob(all_header_files) - Dir.glob(public_header_files) # After spec.private_header_files = Dir.glob(all_header_files).sort - Dir.glob(public_header_files).sort ``` ### Fix 2: Use a Pods-relative path in `hermes-engine.podspec` `require.resolve` with `__dir__` resolves to an absolute path containing the developer's home directory (e.g., `/Users/alice/project/node_modules/...`). This absolute path gets baked into `user_target_xcconfig`, which differs per machine. Instead of hardcoding a relative path (which assumes a specific project layout), we dynamically compute the relative path from `Pod::Config.instance.sandbox.root` to the resolved `hermes-compiler` location. This supports any project layout (standard apps, monorepos, RNTester, etc.) while keeping the xcconfig deterministic. ```ruby # Before — absolute path baked in spec.user_target_xcconfig = { 'HERMES_CLI_PATH' => "#{hermes_compiler_path}/hermesc/osx-bin/hermesc" } # After — dynamic relative path via $(PODS_ROOT) pods_root = Pod::Config.instance.sandbox.root relative_hermesc = Pathname.new(hermesc_path).relative_path_from(pods_root) spec.user_target_xcconfig = { 'HERMES_CLI_PATH' => "$(PODS_ROOT)/#{relative_hermesc}" } ``` bypass-github-export-checks ## Changelog: [IOS] [FIXED] - Make Podfile.lock SPEC CHECKSUMS deterministic across machines by sorting Dir.glob results in Yoga.podspec and using a dynamically computed Pods-relative path in hermes-engine.podspec Pull Request resolved: #56994 Test Plan: 1. Run `pod install` on machine A, record `Podfile.lock` 2. Run `pod install` on machine B (different username/home directory) 3. Verify SPEC CHECKSUMS are identical between both runs We have verified this fix in our production app — after patching, running `pod install` consecutively produces zero diff in `Podfile.lock`. Supersedes #56977 (closed due to force-push history issue). Fixes #56975 Made with [Cursor](https://cursor.com) Reviewed By: cortinico Differential Revision: D107362027 Pulled By: cipolleschi fbshipit-source-id: 8330b99bcd17098f0bcc337ef44372ee9a3e68be
1 parent d30aeeb commit 64c9663

2 files changed

Lines changed: 7 additions & 2 deletions

File tree

packages/react-native/ReactCommon/yoga/Yoga.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,6 @@ Pod::Spec.new do |spec|
6161
# Fabric must be able to access private headers (which should not be included in the umbrella header)
6262
all_header_files = 'yoga/**/*.h'
6363
all_header_files = File.join('ReactCommon/yoga', all_header_files) if ENV['INSTALL_YOGA_WITHOUT_PATH_OPTION']
64-
spec.private_header_files = Dir.glob(all_header_files) - Dir.glob(public_header_files)
64+
spec.private_header_files = Dir.glob(all_header_files).sort - Dir.glob(public_header_files).sort
6565
spec.preserve_paths = [all_header_files]
6666
end

packages/react-native/sdks/hermes-engine/hermes-engine.podspec

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# LICENSE file in the root directory of this source tree.
55

66
require "json"
7+
require "pathname"
78
require_relative "./hermes-utils.rb"
89

910
begin
@@ -70,9 +71,13 @@ Pod::Spec.new do |spec|
7071
hermes_compiler_path = File.dirname(Pod::Executable.execute_command('node', ['-p',
7172
"require.resolve(\"hermes-compiler\", {paths: [\"#{react_native_path}\"]})", __dir__]).strip
7273
)
74+
hermesc_path = File.join(hermes_compiler_path, 'hermesc', 'osx-bin', 'hermesc')
75+
76+
pods_root = Pod::Config.instance.sandbox.root
77+
relative_hermesc = Pathname.new(hermesc_path).relative_path_from(pods_root)
7378

7479
spec.user_target_xcconfig = {
75-
'HERMES_CLI_PATH' => "#{hermes_compiler_path}/hermesc/osx-bin/hermesc"
80+
'HERMES_CLI_PATH' => "$(PODS_ROOT)/#{relative_hermesc}"
7681
}
7782
end
7883

0 commit comments

Comments
 (0)