Опишите типичный CI/CD пайплайн для iOS-проекта.

Ответ

Современный CI/CD для iOS часто строится на связке Fastlane и облачного CI-сервиса (например, GitHub Actions или Bitrise).

Основные этапы пайплайна:

  1. Триггер: Событие в системе контроля версий (push в ветку, pull request).
  2. Сборка зависимостей: bundle install (для Fastlane) и pod install / xcodebuild -resolvePackageDependencies.
  3. Тестирование:
    # Fastlane lane
    run_tests(
      scheme: "MyApp",
      devices: ["iPhone 15"],
      output_directory: "./test_results"
    )
  4. Сборка артефакта:
    # Сборка .ipa или .xcarchive
    build_app(
      scheme: "MyApp",
      export_method: "app-store",
      output_directory: "./build"
    )
  5. Распространение:
    • Внутреннее тестирование: Загрузка в TestFlight (upload_to_testflight) или Firebase App Distribution.
    • Бета-тестирование: Загрузка в сервисы вроде TestFlight для внешних тестеров.
    • Продакшен: Автоматическая отправка в App Store Connect (upload_to_app_store).

Пример конфигурации GitHub Actions:

name: CI
on: [push]
jobs:
  build-and-test:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install Bundler Dependencies
        run: bundle install
      - name: Run Tests
        run: bundle exec fastlane tests
      - name: Build and Upload to TestFlight
        if: github.ref == 'refs/heads/main'
        run: bundle exec fastlane beta

Ключевые практики: Кеширование производных данных (DerivedData), инкрементальные сборки, параллельное выполнение тестов.

Ответ 18+ 🔞

Ну что за жизнь, блядь! Сидишь тут, втыкаешь в этот ваш CI/CD для iOS, а там, сука, одни заклинания: Fastlane, GitHub Actions, Bitrise... Ёперный театр, в рот меня чих-пых! Это ж надо было так всё усложнить, чтобы просто приложение собрать!

Смотри, как оно, блядь, обычно работает, этот твой "современный пайплайн", ага:

  1. Триггер, блядь. Толкнул код в ветку — и понеслась. Или там пулл-реквест создал — всё, система уже проснулась и чешет репу.

  2. Зависимости тянуть. Ну, это святое. bundle install, чтобы Fastlane не взбрыкнул, и pod install или xcodebuild -resolvePackageDependencies, чтобы все библиотеки на местах были. Без этого нихуя не соберётся, проверено.

  3. Тесты гонять. Ну тут всё понятно, надо убедиться, что твой гениальный код не развалил всё к хуям собачьим. В Fastlane это выглядит как-то так:

    # Fastlane lane
    run_tests(
      scheme: "MyApp",
      devices: ["iPhone 15"],
      output_directory: "./test_results"
    )

    Сидит себе, тыкает в интерфейс на симуляторе, а ты в это время кофе пьёшь. Красота.

  4. Собрать артефакт. Ну то есть само приложение, .ipa или архив. Тоже магия простая:

    # Сборка .ipa или .xcarchive
    build_app(
      scheme: "MyApp",
      export_method: "app-store",
      output_directory: "./build"
    )

    Главное — export_method не перепутать, а то вместо тестовой сборки в продакшен попрёшь, и потом волнение ебать.

  5. И наконец, раскидать плоды трудов. Куда душа пожелает:

    • Для своих — в TestFlight (upload_to_testflight) или в Firebase App Distribution. Чтобы коллеги покликали и сказали "чё за хуйня?".
    • Для бета-тестеров — опять же в TestFlight, но уже для внешних. Пусть народ ловит баги за тебя.
    • И наконец, в продакшен — прямиком в App Store Connect (upload_to_app_store). Тут уже страшно, блядь. Нажал кнопку — и жди вердикта от яблочных богов.

А теперь, внимание, сюрприз! Вот тебе пример, как это всё в GitHub Actions выглядит, эта кухня под капотом:

name: CI
on: [push]
jobs:
  build-and-test:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install Bundler Dependencies
        run: bundle install
      - name: Run Tests
        run: bundle exec fastlane tests
      - name: Build and Upload to TestFlight
        if: github.ref == 'refs/heads/main'
        run: bundle exec fastlane beta

Видишь эту строчку if: github.ref == 'refs/heads/main'? Это, блядь, мудрость! Чтобы не палить каждую сборку с левой ветки в TestFlight, а только с главной. А то терпения ноль ебать у тестеров будет.

И запомни главные мантры умных людей: кеширование (чтобы каждый раз не ждать по часу), инкрементальные сборки (чтобы не пересобирать то, что не менялось) и параллельные тесты (чтобы не дохуя времени убивать). Без этого — просто дичь, а не CI/CD, ёпта.