Skip to content

fix: stop restoring a mismatched CocoaPods cache on the TestFlight build - #403

Merged
gdoumen merged 1 commit into
mainfrom
fix/pods-cache-key
Aug 19, 2026
Merged

fix: stop restoring a mismatched CocoaPods cache on the TestFlight build#403
gdoumen merged 1 commit into
mainfrom
fix/pods-cache-key

Conversation

@gdoumen

@gdoumen gdoumen commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

The iOS TestFlight build failed on 2026-08-19:

[!] CocoaPods could not find compatible versions for pod "hermes-engine":
  In snapshot (Podfile.lock): hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
  In Podfile:                 hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
It seems like you've changed the version of the dependency `hermes-engine` and it
differs from the version stored in `Pods/Local Podspecs`.

Both sides name the same source, which is the tell: nothing is wrong with hermes-engine, and nothing was wrong with Podfile.lock either — f73b875 chore: add pod lock had already regenerated it, and I verified that commit was an ancestor of the failed build's sha (4c08207). The lock was correct when the build ran.

Cause: the Pods cache

key: pods-${{ hashFiles('ios/Podfile.lock') }}
restore-keys: pods-
  1. f73b875 changed Podfile.lock (a pod was removed), so the exact cache key missed.
  2. restore-keys: pods- is a prefix fallback matching any earlier pods cache, so it restored ios/Pods from 17 Aug — built from the previous dependency set.
  3. pod install compared the current podspecs against that stale Pods/Local Podspecs and failed.

The history matches: last success 17 Aug, first failure today, and the only thing in between is the dependency set changing.

Fix

Drop the fallback, making the cache exact-hit-or-cold.

ios/Pods is resolved output, valid only for the exact lock that produced it — unlike a package download, where a partial hit is a useful head start. A prefix fallback silently substitutes a directory built from different inputs, which is precisely this failure.

The cost is one full pod install whenever the lock changes, which is exactly when one is wanted. An unchanged lock still hits the exact key, so the common case is unaffected.

The lock hash alone remains a sufficient key — no extra hash inputs are needed: a Podfile change alters PODFILE CHECKSUM inside the lock, and an npm dependency change alters the resolved pod versions in it.

Test plan

  • Workflow YAML parses; the cache step now has key and path only.
  • Not otherwise testable without running the workflow. After merge, the next TestFlight run takes a cold Pods cache once and should go green. If it still fails, the cause is not the cache and the error text should differ.

No Mac-side work is needed — Podfile.lock is already correct in the repo.

The iOS build failed on 2026-08-19 with "could not find compatible versions for
pod hermes-engine ... differs from the version stored in Pods/Local Podspecs",
which reads like a hermes problem but is not one. The Podfile.lock was correct at
that commit.

`ios/Pods` was cached with `key: pods-<hash of Podfile.lock>` and
`restore-keys: pods-`. When the lock changed - a pod had been removed - the exact
key missed, and the prefix fallback happily restored the Pods/ directory from two
days earlier, built from the previous dependency set. `pod install` then compared
the current podspecs against those stale Pods/Local Podspecs and gave up.

Dropping the fallback makes the cache exact-hit-or-cold. `ios/Pods` is resolved
output, valid only for the lock that produced it - unlike a package download,
where a partial hit is a useful head start. The cost is one full `pod install`
whenever the lock changes, which is exactly when one is wanted; an unchanged lock
still hits the exact key and is unaffected.

The lock hash alone remains a sufficient key: a Podfile change alters PODFILE
CHECKSUM inside the lock, and an npm dependency change alters the resolved pod
versions in it.
@sonarqubecloud

Copy link
Copy Markdown

@gdoumen
gdoumen marked this pull request as ready for review August 19, 2026 10:10
@gdoumen
gdoumen merged commit 7accd40 into main Aug 19, 2026
3 checks passed
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