Section 11/221 menit

11. CI/CD Build Optimization

11. CI/CD Build Optimization

GitHub Actions — Strategi Caching Lengkap

swift
# .github/workflows/build.yml
name: iOS Build

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

jobs:
  build:
    runs-on: macos-15
    timeout-minutes: 45

    steps:
      - uses: actions/checkout@v4

      - name: Select Xcode version
        run: sudo xcode-select -s /Applications/Xcode_16.3.app

      # Cache 1: Ruby gems (CocoaPods, Fastlane)
      - name: Cache Ruby Gems
        uses: actions/cache@v4
        with:
          path: vendor/bundle
          key: gems-${{ runner.os }}-${{ hashFiles('Gemfile.lock') }}
          restore-keys: |
            gems-${{ runner.os }}-

      # Cache 2: CocoaPods
      - name: Cache CocoaPods
        uses: actions/cache@v4
        id: cocoapods-cache
        with:
          path: Pods
          key: pods-${{ runner.os }}-xcode16-${{ hashFiles('Podfile.lock') }}
          restore-keys: |
            pods-${{ runner.os }}-xcode16-
            pods-${{ runner.os }}-

      # Cache 3: SPM packages
      - name: Cache SPM
        uses: actions/cache@v4
        with:
          path: |
            ~/Library/Developer/Xcode/DerivedData/**/SourcePackages
            .build
          key: spm-${{ runner.os }}-xcode16-${{ hashFiles('**/Package.resolved') }}
          restore-keys: |
            spm-${{ runner.os }}-xcode16-
            spm-${{ runner.os }}-

      # Cache 4: DerivedData (opsional, efektif untuk incremental build di same branch)
      - name: Cache DerivedData
        uses: actions/cache@v4
        with:
          path: ~/Library/Developer/Xcode/DerivedData
          key: derived-${{ runner.os }}-xcode16-${{ github.ref }}-${{ github.sha }}
          restore-keys: |
            derived-${{ runner.os }}-xcode16-${{ github.ref }}-
            derived-${{ runner.os }}-xcode16-

      - name: Install Ruby dependencies
        run: |
          bundle config path vendor/bundle
          bundle install --jobs 4 --retry 3

      - name: Install CocoaPods
        if: steps.cocoapods-cache.outputs.cache-hit != 'true'
        run: bundle exec pod install --repo-update

      - name: Build and Test
        run: |
          set -o pipefail
          xcodebuild test \
            -workspace MyApp.xcworkspace \
            -scheme MyApp \
            -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.0' \
            -configuration Debug \
            -resultBundlePath TestResults.xcresult \
            CODE_SIGNING_ALLOWED=NO \
            | xcbeautify

      - name: Upload test results
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: test-results
          path: TestResults.xcresult

Parallel Testing

swift
# Pisahkan test suite menjadi beberapa job paralel
jobs:
  test-unit:
    runs-on: macos-15
    steps:
      - # ... setup ...
      - name: Run Unit Tests
        run: xcodebuild test -scheme MyApp -only-testing:MyAppTests ...

  test-ui:
    runs-on: macos-15
    steps:
      - # ... setup ...
      - name: Run UI Tests
        run: xcodebuild test -scheme MyApp -only-testing:MyAppUITests ...

  test-integration:
    runs-on: macos-15
    needs: test-unit  # Integration test setelah unit test selesai
    steps:
      - # ... setup ...
      - name: Run Integration Tests
        run: xcodebuild test -scheme MyApp -only-testing:MyAppIntegrationTests ...