Section 7/151 menit

7. CI Caching untuk CocoaPods

7. CI Caching untuk CocoaPods

CocoaPods memiliki dua layer yang bisa di-cache:

swift
Layer 1: Specs repo (~/.cocoapods/repos/trunk/)
  → Berisi metadata semua pod yang tersedia di CocoaPods CDN
  → Jarang berubah, layak di-cache jangka panjang
  
Layer 2: Pod sources (Pods/ folder)
  → Berisi source code pod yang di-download
  → Berubah saat Podfile.lock berubah
  → Terbesar, paling impactful untuk cache

GitHub Actions: CocoaPods Cache

swift
# .github/workflows/ios-ci.yml

name: iOS CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  build-and-test:
    runs-on: macos-15
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.3'
          bundler-cache: true  # Auto-cache gems termasuk CocoaPods

      # Cache CocoaPods specs repo (metadata)
      # Cache key: hash dari versi CocoaPods — jarang berubah
      - name: Cache CocoaPods Specs
        uses: actions/cache@v4
        with:
          path: ~/.cocoapods/repos/trunk
          key: cocoapods-specs-${{ hashFiles('Podfile.lock') }}
          restore-keys: |
            cocoapods-specs-

      # Cache Pods folder (sources)
      # Cache key: hash dari Podfile.lock — berubah saat dependency berubah
      - name: Cache CocoaPods Sources
        id: pods-cache
        uses: actions/cache@v4
        with:
          path: Pods
          key: pods-${{ runner.os }}-${{ hashFiles('Podfile.lock') }}
          restore-keys: |
            pods-${{ runner.os }}-

      # Jalankan pod install hanya jika cache miss
      - name: Install CocoaPods
        if: steps.pods-cache.outputs.cache-hit != 'true'
        run: bundle exec pod install --no-repo-update

      - name: Build & Test
        run: |
          xcodebuild test \
            -workspace MyApp.xcworkspace \
            -scheme MyApp \
            -destination "platform=iOS Simulator,name=iPhone 16 Pro" \
            | xcpretty

Bitrise: CocoaPods Cache

swift
# bitrise.yml

workflows:
  primary:
    steps:
      - git-clone: {}
      
      - restore-cache@2:
          inputs:
            - key: cocoapods-{{ checksum "Podfile.lock" }}
            - key: cocoapods-
          
      - cocoapods-install@2:
          inputs:
            - install_cocoapods_version: "1.15.2"
            - is_cache_disabled: "false"
            
      - save-cache@1:
          inputs:
            - key: cocoapods-{{ checksum "Podfile.lock" }}
            - paths: |
                ./Pods
                ~/.cocoapods/repos/trunk

Xcode Cloud: CocoaPods Cache

Xcode Cloud tidak memiliki built-in caching untuk CocoaPods. Gunakan ci_scripts:

swift
#!/bin/sh
# ci_scripts/ci_post_clone.sh

set -e

echo "Installing CocoaPods dependencies..."

# Install bundler dan gems (termasuk cocoapods)
gem install bundler --no-document
bundle install

# Install pods
bundle exec pod install --no-repo-update

echo "✓ CocoaPods installation complete"
swift
# Di Xcode Cloud, untuk mengurangi waktu pod install:
# 1. Gunakan --no-repo-update (tidak update specs repo)
# 2. Gunakan CDN source di Podfile (lebih cepat dari git specs repo)

# Podfile:
source 'https://cdn.cocoapods.org/'  # CDN lebih cepat dari git clone

Cache Strategy Best Practices (CocoaPods)

swift
# Cache key yang direkomendasikan:
# Level 1 (paling spesifik): OS + Podfile.lock hash
# Level 2 (fallback): OS saja
# Level 3 (last resort): tanpa key (any cache)

- name: Cache Pods
  uses: actions/cache@v4
  with:
    path: Pods
    key: pods-${{ runner.os }}-${{ hashFiles('**/Podfile.lock') }}
    restore-keys: |
      pods-${{ runner.os }}-
      pods-
      
# Tips tambahan:
# - Selalu commit Podfile.lock — ini adalah basis cache key yang stabil
# - Pisahkan cache specs repo dan Pods/ — specs berubah lebih jarang
# - Untuk monorepo dengan banyak target: path bisa include multiple Pods/ folders