fix(ci): improve CocoaPods install resilience against CDN rate limiting#29334
Conversation
Remove the standalone `pod repo remove trunk` step that runs before every `pod install`. On ephemeral Cirrus runners the only source of trunk specs is the actions/cache restore — deleting them forces a full CDN re-download (thousands of HTTP requests) on every run, increasing the surface area for 429 rate-limit errors. Move trunk removal into `on_retry_command` so cached specs are used for an incremental `--repo-update` on the first attempt (low CDN load), and only cleared on failure for a clean retry. Additional improvements: - Increase max_attempts from 2 to 3 (matches other retry steps) - Increase retry_wait_seconds from 30 to 60 (longer backoff for CDN 429) - Add ::warning:: annotation on retry for visibility in Actions UI - Add COCOAPODS_DISABLE_STATS=true to skip analytics during CI Made-with: Cursor
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
🔍 Smart E2E Test Selection⏭️ Smart E2E selection skipped - skip-smart-e2e-selection label found All E2E tests pre-selected. |
|
On hold pending #29247. PR #29247 ( |
|
✅ E2E Fixture Validation — Schema is up to date |
|



Description
Problem
CocoaPods CDN rate limiting accounts for 7% (~4 runs) of Setup Environment CI failures on
mainover 30 days (Mar 16 – Apr 16, 2026), per INFRA-3580 analysis. The error signatures are:CDN: trunk URL couldn't be downloaded ... Response: 429 Too Many Requestspod installRoot Cause
The current flow in
setup-e2e-env/action.ymldefeats its own CocoaPods specs cache:actions/cache@v4restores~/.cocoapods/repos(including trunk specs) — 100% cache hit rate observedpod repo remove trunk || trueimmediately deletes the restored trunk specspod install --repo-updatemust re-download the entire trunk fromcdn.cocoapods.org— thousands of HTTP requestsThis maximises CDN pressure on every single iOS CI run, increasing the surface area for 429 rate-limit errors.
When trunk exists locally,
--repo-updateperforms an incremental delta update — minimal CDN requests, fast.Without trunk (after removal),
--repo-updatedownloads everything from scratch — heavy CDN load, slow, triggers 429s.Why
pod repo remove trunkwas addedThe step was added in PR #28433 (commit
bc06cd5123, Apr 8, 2026) as part of the macOS Sequoia → Tahoe migration for Xcode 26.x support. It was added proactively with the comment "prevent stale specs" — no review comments discussed the rationale, and no specific CDN failure motivated it.Since Cirrus runners are ephemeral (VMs destroyed after each job — confirmed by Cirrus Labs: "Every job is executed in a reproducible isolated environment which is completely destroyed after the job is finished"), the only way trunk specs exist at the start of
pod installis via theactions/cacherestore. There is no leftover state from previous jobs. The--repo-updateflag already handles staleness by fetching deltas when trunk exists locally.Data
Pod install timing (successful runs, with trunk removal + full CDN re-download):
CocoaPods specs cache hit rate: 100% (exact or restore-key match in all sampled runs)
Cache flow (current, counterproductive):
pod repo remove trunk: deletes restored specs → trunk gonepod install --repo-update: full CDN download → thousands of requests → 429 riskSolution
pod repo remove trunkstep — let cached specs be used on first attempt for incremental--repo-update(low CDN load)on_retry_command— only clean on failure (handles corrupt/stale cache edge case)max_attemptsfrom 2 to 3 — matches other retry steps in the same file; CDN rate limits may need a third attemptretry_wait_secondsfrom 30 to 60 — CDN 429 backoff windows need longer wait than apt mirror desyncs::warning::annotation on retry — makes CDN failures visible in GitHub Actions UICOCOAPODS_DISABLE_STATS=true— eliminates unnecessary analytics network calls during CIFirst attempt (happy path): cached trunk specs + incremental
--repo-update→ few HTTP requests, low CDN loadOn failure: trunk removed for clean slate → full CDN download on retry, warned in Actions UI
Second/third attempt: fresh download from CDN with 60s backoff between attempts
Changelog
CHANGELOG entry: null
Related issues
Refs: INFRA-3580
Manual testing steps
N/A — CI infrastructure change. Validated by any iOS E2E workflow run (retry logic is transparent in the happy path). The
pod installstep behavior is identical when the first attempt succeeds.Screenshots/Recordings
Before
N/A
After
N/A
Pre-merge author checklist
Pre-merge reviewer checklist
Made with Cursor
Note
Medium Risk
Changes the iOS CI dependency install flow and retry behavior, which could affect build stability if cache state differs from expectations, but it is limited to CI setup and guarded by retries.
Overview
Improves iOS E2E CI CocoaPods installation reliability by stopping the unconditional
pod repo remove trunkcleanup so the restored CocoaPods specs cache can be used on the firstpod install --repo-updateattempt.The CocoaPods install retry policy is strengthened (attempts 2→3, wait 30s→60s), and trunk cleanup is moved into
on_retry_commandwith a GitHub Actions::warning::annotation;COCOAPODS_DISABLE_STATS=trueis added to reduce extra network calls during CI.Reviewed by Cursor Bugbot for commit 13ce7a7. Bugbot is set up for automated code reviews on this repo. Configure here.