CI/CD для Swift проектов: GitHub Actions пошаговое руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Зачем нужен CI/CD для Swift проектов?

Разработка под iOS и macOS требует высокой культуры кода и надежности. Каждое изменение может сломать билд или привести к регрессиям в тестах. Ручная проверка — медленный и ненадежный процесс. Именно здесь на помощь приходит CI/CD (Continuous Integration / Continuous Deployment) — непрерывная интеграция и доставка.

GitHub Actions — это мощный и встроенный инструмент для автоматизации рабочих процессов прямо в вашем репозитории. Он позволяет автоматически собирать проект, запускать тесты, анализировать код и даже публиковать приложение в App Store или TestFlight при каждом пуше или создании Pull Request.

В этой статье мы разберем, как настроить полноценный CI/CD пайплайн для Swift проекта на GitHub Actions. Вы узнаете, как создать workflow, настроить сборку, прогон тестов, линтинг и деплой. Все примеры кода готовы к использованию.

Основная часть

1. Основы GitHub Actions для Swift

GitHub Actions работает на основе YAML-файлов, которые хранятся в директории .github/workflows/. Каждый файл описывает один или несколько workflow (рабочих процессов). Для Swift проекта нам потребуется runner с macOS, так как сборка iOS/macOS приложений возможна только на этой платформе.

Базовый workflow для Swift проекта выглядит так:

name: Swift CI

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  build-and-test:
    runs-on: macos-latest

    steps:
    - uses: actions/checkout@v4

    - name: Build
      run: swift build

    - name: Run tests
      run: swift test

Разберем ключевые моменты:

  • on — триггеры: запуск на push и pull request в main.
  • runs-on: macos-latest — используем последнюю версию macOS для runner.
  • actions/checkout — стандартный action для клонирования репозитория.
  • swift build и swift test — команды Swift Package Manager.

Этот минимальный пайплайн уже обеспечивает базовую проверку. Но для реального iOS/macOS приложения этого недостаточно — нужно настроить Xcode, симуляторы и зависимости.

2. Настройка сборки и тестов для iOS/macOS приложения

Если ваш проект использует Xcode (например, .xcworkspace или .xcodeproj), команда swift build не подойдет. Вместо этого используем xcodebuild. Также нужно указать схему и destination (например, симулятор iPhone).

Пример workflow для iOS приложения:

name: iOS CI

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

jobs:
  test:
    runs-on: macos-14

    steps:
    - uses: actions/checkout@v4

    - name: Select Xcode version
      run: sudo xcode-select -s /Applications/Xcode_15.2.app

    - name: Install CocoaPods (если используете)
      run: pod install

    - name: Build and Test
      run: |
        xcodebuild clean test \
          -workspace YourApp.xcworkspace \
          -scheme "YourApp Scheme" \
          -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.2' \
          -resultBundlePath TestResults
      env:
        DEVELOPER_DIR: /Applications/Xcode_15.2.app/Contents/Developer

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

Важные детали:

  • macos-14 — используем macOS 14 Sonoma с Xcode 15.2.
  • xcode-select — явно указываем версию Xcode, чтобы избежать несовместимости.
  • resultBundlePath — сохраняем результаты тестов как артефакт для дальнейшего анализа.
  • upload-artifact — загружаем отчеты о тестах, даже если они упали (if: always()).

Для macOS приложения destination будет другим:

-destination 'platform=macOS,arch=x86_64'

3. Добавление линтинга и статического анализа

Качество кода — залог успеха. Добавим в пайплайн проверку стиля с помощью SwiftLint и статический анализ с помощью SwiftFormat или собственных скриптов.

Пример шага для SwiftLint:

    - name: Run SwiftLint
      run: |
        brew install swiftlint
        swiftlint --strict

Чтобы не устанавливать SwiftLint каждый раз, можно использовать готовый action:

    - name: SwiftLint
      uses: norio-nomura/action-swiftlint@3.2.1
      with:
        args: --strict

Также полезно добавить проверку на наличие TODO и FIXME комментариев:

    - name: Check for TODOs
      run: |
        if grep -r "TODO" --include="*.swift" .; then
          echo "Found TODO comments"
          exit 1
        fi

Все эти шаги помогут поддерживать код в чистоте и предотвращать попадание технического долга в основную ветку.

4. Автоматический деплой в TestFlight или App Store

Финальный этап CI/CD — автоматическая доставка. Для Swift проектов это обычно публикация в TestFlight (для beta-тестеров) или в App Store. GitHub Actions позволяет это сделать с помощью сторонних actions или через fastlane.

Пример с использованием fastlane (предварительно настройте Fastfile):

    - name: Deploy to TestFlight
      if: github.ref == 'refs/heads/main'
      run: |
        bundle exec fastlane beta
      env:
        APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
        APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
        APP_STORE_CONNECT_API_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_ISSUER_ID }}

Важно: Все секреты (API ключи, пароли) храните в Settings > Secrets and variables > Actions вашего репозитория. Никогда не вставляйте их в код!

Альтернатива — использование action apple-actions/upload-testflight-build:

    - name: Upload to TestFlight
      uses: apple-actions/upload-testflight-build@v1
      with:
        app                

Блоги

Рекомендаций по книгам