Введение в CI/CD для Swift проектов
Современная разработка мобильных и десктопных приложений на Swift требует не только качественного кода, но и надёжного процесса интеграции и доставки изменений. Continuous Integration (CI) и Continuous Delivery (CD) — это практики, которые позволяют автоматизировать сборку, тестирование и развёртывание приложений. GitHub Actions — встроенный инструмент GitHub, который идеально подходит для Swift проектов, работающих на iOS и macOS.
В этой статье мы разберём полный цикл настройки CI/CD для Swift: от базовой конфигурации до деплоя в App Store и TestFlight. Вы узнаете, как ускорить разработку, избежать «человеческого фактора» и обеспечить стабильность вашего приложения.
Основные компоненты CI/CD для Swift
Прежде чем перейти к настройке, важно понять, из каких этапов состоит пайплайн для Swift проектов:
- Сборка (Build) — компиляция проекта с помощью Xcode или xcodebuild.
- Тестирование (Test) — запуск юнит-тестов и UI-тестов.
- Линтинг (Lint) — проверка стиля кода (например, с помощью SwiftLint).
- Архивация (Archive) — создание .ipa или .app файла для деплоя.
- Деплой (Deploy) — отправка сборки в TestFlight или App Store.
GitHub Actions позволяет объединить все эти шаги в одном YAML-файле, который хранится в репозитории.
Настройка GitHub Actions для Swift: пошаговое руководство
1. Создание workflow файла
Создайте в корне репозитория папку .github/workflows и добавьте файл ci.yml:
name: Swift CI/CD
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build-and-test:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Select Xcode version
run: sudo xcode-select -s /Applications/Xcode_15.0.app/Contents/Developer
- name: Build and test
run: |
xcodebuild clean test \
-project YourApp.xcodeproj \
-scheme YourApp \
-destination 'platform=iOS Simulator,name=iPhone 15,OS=17.0' \
-resultBundlePath TestResults \
CODE_SIGNING_ALLOWED=NO
- name: Upload test results
uses: actions/upload-artifact@v4
with:
name: test-results
path: TestResults.xcresult
Этот workflow запускается при каждом пуше в main и develop, а также на pull request. Он выполняет чистую сборку и прогоняет все тесты на симуляторе iPhone 15 с iOS 17.
2. Добавление линтинга и статического анализа
Чтобы поддерживать единый стиль кода, добавьте шаг с SwiftLint:
- name: Run SwiftLint
run: |
brew install swiftlint
swiftlint --strict
Если вы используете SPM (Swift Package Manager), можно добавить статический анализ с помощью swift analyze (доступно в Swift 5.9+):
- name: Static analysis
run: swift analyze --strict
3. Настройка CD: деплой в TestFlight
Для автоматической доставки сборок в TestFlight потребуются сертификаты и профили подписи. Самый безопасный способ — использовать GitHub Secrets для хранения ключей:
jobs:
deploy:
needs: build-and-test
runs-on: macos-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Install provisioning profile
env:
PROVISIONING_PROFILE: ${{ secrets.PROVISIONING_PROFILE_BASE64 }}
run: |
echo "$PROVISIONING_PROFILE" | base64 --decode > ~/Library/MobileDevice/Provisioning\ Profiles/profile.mobileprovision
- name: Build and archive
run: |
xcodebuild archive \
-project YourApp.xcodeproj \
-scheme YourApp \
-archivePath $RUNNER_TEMP/YourApp.xcarchive \
-allowProvisioningUpdates
- name: Export IPA
run: |
xcodebuild -exportArchive \
-archivePath $RUNNER_TEMP/YourApp.xcarchive \
-exportPath $RUNNER_TEMP/YourApp.ipa \
-exportOptionsPlist ExportOptions.plist
- name: Upload to TestFlight
uses: apple-actions/upload-testflight-build@v1
with:
ipa-path: $RUNNER_TEMP/YourApp.ipa
apple-id: ${{ secrets.APPLE_ID }}
app-specific-password: ${{ secrets.APP_SPECIFIC_PASSWORD }}
В ExportOptions.plist нужно указать метод экспорта (например, app-store) и идентификатор команды.
4. Оптимизация времени выполнения
Swift проекты могут собираться долго. Используйте кэширование зависимостей и результатов сборки:
- name: Cache SPM dependencies
uses: actions/cache@v4
with:
path: .build
key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}
restore-keys: |
${{ runner.os }}-spm-
- name: Cache derived data
uses: actions/cache@v4
with:
path: ~/Library/Developer/Xcode/DerivedData
key: ${{ runner.os }}-derived-${{ github.sha }}
restore-keys: |
${{ runner.os }}-derived-
Это может сократить время сборки на 50–70%.
Распространённые ошибки и их решение
- Ошибка подписи кода — всегда используйте
CODE_SIGNING_ALLOWED=NOдля тестовой сборки. Для деплоя храните сертификаты в GitHub Secrets. - Неверная версия Xcode — явно указывайте версию через
xcode-select, так как macOS-раннеры имеют несколько версий Xcode. - Проблемы с симулятором — убедитесь, что указанная платформа и версия ОС существуют. Можно использовать
xcrun simctl listдля проверки. - Долгая сборка — помимо кэширования, используйте параллельные джобы для разных схем или платформ.
Заключение
GitHub Actions предоставляет мощный и гибкий инструмент для автоматизации CI/CD процессов Swift проектов. Мы рассмотрели базовую сборку, тестирование, линтинг, статический анализ и деплой в TestFlight. Главные преимущества такого подхода: