Skip to content

fix(cocoapods) Podfile.lock SPEC CHECKSUMS drift for React XCFrameworks#56803

Closed
chrfalch wants to merge 1 commit into
mainfrom
chrfalch/reduce-cocoapods-checksum-drifting
Closed

fix(cocoapods) Podfile.lock SPEC CHECKSUMS drift for React XCFrameworks#56803
chrfalch wants to merge 1 commit into
mainfrom
chrfalch/reduce-cocoapods-checksum-drifting

Conversation

@chrfalch
Copy link
Copy Markdown
Collaborator

@chrfalch chrfalch commented May 12, 2026

Summary:

Two developers (or one developer on two paths, or CI vs. local) running pod install on the same React Native project at the same commit get different SPEC CHECKSUMS entries for React-Core-prebuilt and ReactNativeDependencies in Podfile.lock.

That breaks pod install-deployment style verification and any workflow that expects Podfile.lock to be reproducible.

CocoaPods derives SPEC CHECKSUMS entry by hashing the in-memory podspec JSON. Anything embedded in source.http, prepare_command, user_target_xcconfig, etc. becomes part of the hash.

Problem: Two podspec-resolution sites in this repo build their source.http from an absolute on-disk path, because project_pods_root is an absolute path, the resulting file:///... URL differs across machines or working-tree paths, so the hashed JSON differs, so the checksum differs.

How

The Maven URL for each tarball is already computed inside both functions (stable_tarball_url(...) / nightly_tarball_url(...) / release_tarball_url(...)). Returning that URL — a stable string identical across machines — instead of the local file:// URL makes source.http path-free. CocoaPods downloads from Maven and caches the tarball itself, so functionality is preserved.

The pre-existing local-tarball download is kept untouched (its only remaining consumer is the opt-in RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS=1 dSYM-injection path in rncore.rb, which still needs file:// to feed CocoaPods a mutated tarball — gated by unless @@download_dsyms so the leak is preserved only for that flag).

**Out of scope: **

hermes-engine.podspec has the same shape of leak in user_target_xcconfig.HERMES_CLI_PATH. Fixing it requires a paired change to ensure hermesc lands at the new ${PODS_ROOT}-relative path; that's a separate PR.

NOTE:

In our scripts for downloading XCFrameworks we implemented the original problematic solution returning a full file path to avoid double downloading on pod install. (We need to know the location of these tarballs so that the script that switches between release/debug will work). With this solution, which is the correct way to solve this, we'll both let Cocoapods download (through its cache) the tarballs - and we'll download the release/debug artifacts. This is redundant, but hard to avoid without rewriting the download code completely - this can be done in a follow-up PR.

Changelog:

[IOS] [FIXED] - Fix Pod install checksum drifting

Test Plan:

Run pod install and verify that none of the following files contains absolute paths:

  • Pods/Local Podspecs/React-Core-prebuilt.podspec.json
  • Pods/Local Podspecs/ReactNativeDependencies.podspec.json

**Symptom:**

Two developers (or one developer on two paths, or CI vs. local) running pod install on the same React Native project at the same commit get different SPEC CHECKSUMS entries for React-Core-prebuilt and ReactNativeDependencies in Podfile.lock. That breaks pod install-deployment style verification and any workflow that expects Podfile.lock to be reproducible.

Root cause:
CocoaPods derives each SPEC CHECKSUMS entry by hashing the in-memory podspec JSON. So anything embedded in source.http, prepare_command, user_target_xcconfig, etc. becomes part of the hash. Two podspec-resolution sites in this repo build their source.http from an absolute on-disk path.

Because project_pods_root is an absolute path, the resulting file://<abs>/... URL differs across machines or working-tree paths, so the hashed JSON differs, so the checksum differs.

**Fix: **
The Maven URL for each tarball is already computed inside both functions (stable_tarball_url(...) / nightly_tarball_url(...) / release_tarball_url(...)). Returning that URL — a stable string identical across machines — instead of the local file:// URL makes source.http path-free. CocoaPods downloads from Maven and caches the tarball itself, so functionality is preserved.

The pre-existing local-tarball download is kept untouched (its only remaining consumer is the opt-in  `RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS=1` dSYM-injection path in rncore.rb, which still needs file:// to feed CocoaPods a mutated tarball — gated by unless @@download_dsyms so the leak is preserved only for that flag).

**Out of scope: **

hermes-engine.podspec has the same shape of leak in user_target_xcconfig.HERMES_CLI_PATH. Fixing it requires a paired change to ensure hermesc lands at the new ${PODS_ROOT}-relative path; that's a separate PR.
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label May 12, 2026
@facebook-github-tools facebook-github-tools Bot added p: Expo Partner: Expo Partner Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. labels May 12, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync Bot commented May 12, 2026

@CalixTang has imported this pull request. If you are a Meta employee, you can view this in D104889112.

@chrfalch chrfalch requested a review from cipolleschi May 13, 2026 06:08
@meta-codesync meta-codesync Bot closed this in 814ebb1 May 13, 2026
@facebook-github-tools facebook-github-tools Bot added the Merged This PR has been merged. label May 13, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync Bot commented May 13, 2026

@CalixTang merged this pull request in 814ebb1.

@react-native-bot
Copy link
Copy Markdown
Collaborator

This pull request was successfully merged by @chrfalch in 814ebb1

When will my fix make it into a release? | How to file a pick request?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged This PR has been merged. p: Expo Partner: Expo Partner Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants