From 949f2469b7f684dde49bd3ca7e315518c4fc89d4 Mon Sep 17 00:00:00 2001 From: Thiago Brezinski Date: Sun, 6 Sep 2026 10:36:34 +0100 Subject: [PATCH 1/2] ci: always run pod install in the contract job, even on a Pods cache hit (#98) React Native codegen runs inside pod install and writes its generated sources to example/ios/build/generated, outside the cached Pods path, so skipping pod install on an exact cache hit leaves the ReactCodegen pod target pointing at files that do not exist and every iOS contract build fails within a minute. Keep the cache as a warm-checkout speedup only, mirroring the convention already documented in ci.yml. Co-Authored-By: Claude Fable 5 --- .github/workflows/exact-package-candidate.yml | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/exact-package-candidate.yml b/.github/workflows/exact-package-candidate.yml index 2b99ba3..6178aa5 100644 --- a/.github/workflows/exact-package-candidate.yml +++ b/.github/workflows/exact-package-candidate.yml @@ -505,7 +505,6 @@ jobs: - name: Cache cocoapods if: runner.os == 'macOS' - id: cocoapods-cache uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: example/ios/Pods @@ -515,20 +514,22 @@ jobs: - name: Verify Apple runtime and prepare native app if: runner.os == 'macOS' - env: - COCOAPODS_CACHE_HIT: ${{ steps.cocoapods-cache.outputs.cache-hit }} run: | xcrun simctl list runtimes | grep -F '${{ matrix.runtime }}' brew tap wix/brew brew trust --formula wix/brew/applesimutils brew install wix/brew/applesimutils - if [[ "$COCOAPODS_CACHE_HIT" != 'true' ]]; then - ( - cd example - bundle install - bundle exec pod install --project-directory=ios - ) - fi + # Always run pod install, even on a Pods cache hit: React Native + # codegen runs inside pod install and writes its sources to + # example/ios/build/generated, which is outside the cached Pods + # directory, so a restored cache alone leaves the ReactCodegen pod + # target pointing at files that do not exist. The cache still pays + # for itself by keeping the Pods checkout warm. + ( + cd example + bundle install + bundle exec pod install --project-directory=ios + ) # build-framework-cache must run before detox build: without a # prebuilt framework cache, Detox compiles it lazily mid-build and # the Apple contract build fails on hosted runners. From 1d47258717f1c761cfea25c0a5fe8cd1c931104c Mon Sep 17 00:00:00 2001 From: Thiago Brezinski Date: Sun, 6 Sep 2026 10:51:22 +0100 Subject: [PATCH 2/2] ci: give the contract job its own cocoapods cache namespace (#98) The contract job installs the packed candidate tarball and pod-installs for Release Detox builds, but saved that Pods tree under the same macOS-cocoapods- key ci.yml uses for its Debug build. When build-ios restored the contract job's entry from main, pod install saw an in-sync sandbox (only Reorderable was reinstalled) and the Debug app linked against Release prebuilt React core binaries, failing on debug-only symbols such as Props::getDebugProps. Prefix the contract key so the two flavors can never alias; the poisoned main entry has been deleted from the Actions cache. Co-Authored-By: Claude Fable 5 --- .github/workflows/exact-package-candidate.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/exact-package-candidate.yml b/.github/workflows/exact-package-candidate.yml index 6178aa5..7abade0 100644 --- a/.github/workflows/exact-package-candidate.yml +++ b/.github/workflows/exact-package-candidate.yml @@ -508,9 +508,16 @@ jobs: uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: example/ios/Pods - key: ${{ runner.os }}-cocoapods-${{ hashFiles('example/ios/Podfile.lock') }} + # The contract- prefix keeps this cache disjoint from ci.yml's + # cocoapods cache: this job installs the packed candidate tarball + # and builds Release for Detox, so its Pods tree (notably the + # prebuilt React core binaries) is Release-flavored. Sharing a key + # with ci.yml's Debug build once poisoned build-ios with + # release-only core binaries and failed the link on debug-only + # symbols. + key: ${{ runner.os }}-contract-cocoapods-${{ hashFiles('example/ios/Podfile.lock') }} restore-keys: | - ${{ runner.os }}-cocoapods- + ${{ runner.os }}-contract-cocoapods- - name: Verify Apple runtime and prepare native app if: runner.os == 'macOS'