Skip to content

[build-tools] support remote CocoaPods caching - #4266

Open
AbbanMustafa wants to merge 5 commits into
mainfrom
mustafa/cocoapods-build-cache
Open

[build-tools] support remote CocoaPods caching#4266
AbbanMustafa wants to merge 5 commits into
mainfrom
mustafa/cocoapods-build-cache

Conversation

@AbbanMustafa

@AbbanMustafa AbbanMustafa commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Why

CocoaPods dependencies are installed from scratch on every iOS build. For projects with large dependency graphs, pod install can add several minutes even when Podfile.lock has not changed.

Local validation with 107 pods showed that remote Pods caching reduced the relevant phases from 111 seconds to 42 seconds.

The cache-hit validation started with no Podfile.lock present. It requested the ios-pods-1.16.2- prefix, restored the hash-qualified ios-pods-1.16.2-5c51d462... entry, and completed the iOS build successfully.

How

  • Add opt-in CocoaPods caching with EAS_PODS_CACHE=1.
  • Cache ios/Pods under the exact key ios-pods-<cocoapods-version>-<sha256-of-Podfile.lock>.
  • When a managed project has no lockfile before prebuild, request the ios-pods-<cocoapods-version>- prefix and restore its newest matching entry.
  • Always run pod install to reconcile restored Pods with the generated lockfile.
  • Save the resulting Pods directory under the exact lockfile key.
  • Support traditional, custom, and simulator iOS builds.
  • Treat cache failures as non-fatal.

~/Library/Caches/CocoaPods is intentionally excluded. In local testing, its 435 MB archive added approximately 33 seconds of restore time and 42 seconds of recompression on a cache hit.

Test Plan

  • Run focused build-tools tests: 16 passed.
  • Run build-tools typecheck.
  • Run repository lint.
  • Run changelog lint.
  • Populate the cache from a managed iOS build.
  • Restore the cache on a subsequent managed iOS build.
  • Validate prefix fallback when no Podfile.lock exists before prebuild.
  • Run the cache-hit build with ~/Library/Caches/CocoaPods removed to simulate a fresh worker.
  • Confirm the cache-hit build completes without CocoaPods downloads.
  • Measure a 242 MB Pods archive.
  • Measure install phases:
Scenario Restore Install pods Save Total
Cold, cache disabled 1s 110s 111s
Cold worker, cache hit 15s 17s 10s 42s

@codecov

codecov Bot commented Aug 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.73469% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.09%. Comparing base (66dbcaf) to head (11a0961).

Files with missing lines Patch % Lines
...ild-tools/src/steps/functions/restoreBuildCache.ts 76.00% 6 Missing ⚠️
.../build-tools/src/steps/functions/saveBuildCache.ts 80.00% 5 Missing ⚠️
packages/build-tools/src/utils/cocoapodsCache.ts 95.56% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4266      +/-   ##
==========================================
+ Coverage   64.05%   64.09%   +0.05%     
==========================================
  Files        1042     1043       +1     
  Lines       48009    48107      +98     
  Branches    10130    10141      +11     
==========================================
+ Hits        30745    30830      +85     
- Misses      17148    17161      +13     
  Partials      116      116              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@AbbanMustafa AbbanMustafa changed the title [build-tools] Cache CocoaPods dependencies between iOS builds [build-tools] support remote CocoaPods caching Aug 24, 2026
@AbbanMustafa
AbbanMustafa marked this pull request as ready for review August 26, 2026 05:29
@github-actions

Copy link
Copy Markdown

✅ Thank you for adding the changelog entry!

@AbbanMustafa
AbbanMustafa requested a review from sjchmiela August 26, 2026 06:10

@sjchmiela sjchmiela left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it!

Comment on lines 106 to +119
await ctx.cacheManager?.restoreCache(ctx);
await restoreCcacheAsync({
logger: ctx.logger,
workingDirectory,
target: { platform: ctx.job.platform, simulator: ctx.job.simulator === true },
env: ctx.env,
secrets: ctx.job.secrets,
});
await restoreCocoapodsCacheAsync({
logger: ctx.logger,
workingDirectory,
env: ctx.env,
secrets: ctx.job.secrets,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder if it would make sense to parallelize them some time

maybe not in this PR

this is going to create weird log output

Comment on lines +263 to +268
await saveCocoapodsCacheAsync({
logger: ctx.logger,
workingDirectory,
env: ctx.env,
secrets: ctx.job.secrets,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

};
}

export async function compressCocoapodsCacheAsync({

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we prefer this over compressCacheAsync?

});
}

export async function saveCocoapodsCacheAsync({

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to prune the cache somehow too? what's the plan here?

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.

2 participants