Ваш Swift-проект заслуживает автоматического неба: строим CI/CD с нуля
Вы написали крутой Swift-пакет или приложение. Код летает, тесты проходят локально, вы чувствуете себя рок-звездой. Но стоит сделать push — и начинается ад: «А на Linux соберётся?», «А тесты на macOS пройдут?», «А вдруг я забыл запустить SwiftLint?».
Знакомо? Если да — вам нужен CI/CD pipeline для Swift. Это как автопилот для вашего кода: он сам собирает, тестирует, проверяет стиль и даже деплоит. В этой статье мы настроим CI/CD pipeline Swift с нуля на примере GitHub Actions. Вы получите готовый рабочий код, который можно скопировать и использовать уже сегодня.
Спойлер: после настройки вы будете получать зелёные галочки на каждый commit, а не седеть над консолью.
Почему CI/CD для Swift — это не роскошь, а необходимость
Swift живёт в двух мирах: macOS (Xcode, CocoaPods, Carthage) и Linux (Vapor, SwiftNIO, серверные проекты). Без CI/CD вы рискуете:
- Пропустить ошибку компиляции на другой платформе
- Забыть запустить линтер (а потом код выглядит как после бомбёжки)
- Тратить часы на ручной деплой
- Потерять время на поиск регрессий
Правильно настроенный Swift CI/CD pipeline решает все эти проблемы. Он работает 24/7, не пьёт кофе и не говорит «а у меня всё работает». Поехали!
Шаг 1: Выбираем инструмент — GitHub Actions
Мы будем использовать GitHub Actions — это встроенный CI/CD в GitHub, и для Swift он идеален. Причины:
- Бесплатно для публичных репозиториев (2000 минут в месяц)
- macOS раннеры — можно собрать под Xcode
- Linux раннеры — для серверных Swift-проектов
- Готовые actions для SwiftLint, тестов, деплоя
Если вы используете GitLab, Bitbucket или Jenkins — принципы те же, но синтаксис YAML будет отличаться.
Шаг 2: Базовая структура CI/CD pipeline для Swift
Любой pipeline состоит из трёх этапов:
- Build — сборка проекта (SPM или Xcode)
- Test — запуск Unit-тестов
- Lint — проверка стиля кода (опционально, но очень желательно)
Дополнительно можно добавить деплой (например, на сервер или в TestFlight).
Создаём файл .github/workflows/swift-ci.yml
В корне вашего репозитория создайте папку .github/workflows/ и внутри файл swift-ci.yml. Вот минимальный рабочий pipeline:
name: Swift CI/CD Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Swift
uses: swift-actions/setup-swift@v1
with:
swift-version: "5.9"
- name: Build
run: swift build
- name: Run tests
run: swift test
Этот CI/CD pipeline для Swift запускается при каждом push или pull request в main/develop. Он собирает проект и прогоняет тесты на Ubuntu. Просто? Да. Но давайте добавим магии.
Шаг 3: Добавляем macOS и Xcode в матрицу сборки
Swift-разработчики часто работают на macOS, а серверная часть — на Linux. Чтобы быть уверенным, что проект собирается везде, используем матрицу стратегий (matrix strategy):
jobs:
build-and-test:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
swift-version: ["5.8", "5.9"]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Setup Swift
uses: swift-actions/setup-swift@v1
with:
swift-version: ${{ matrix.swift-version }}
- name: Build
run: swift build
- name: Test
run: swift test
Теперь pipeline проверит 4 комбинации: Ubuntu + Swift 5.8, Ubuntu + Swift 5.9, macOS + Swift 5.8, macOS + Swift 5.9. Это настоящий Swift CI/CD pipeline с кроссплатформенным покрытием.
Совет: если ваш проект использует Xcode (iOS/macOS), заменитеswift buildнаxcodebuildс указанием схемы и workspace.
Шаг 4: SwiftLint — автоматическая проверка стиля
Код без единого стиля — это боль. SwiftLint помогает её избежать. Добавим его в pipeline:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: SwiftLint
uses: norio-nomura/action-swiftlint@3.2.1
with:
args: --strict
Параметр --strict делает любые предупреждения ошибками — pipeline упадёт, если стиль нарушен. Жёстко, но эффективно.
Если вы хотите настроить правила — создайте в корне проекта файл .swiftlint.yml:
disabled_rules:
- trailing_whitespace
opt_in_rules:
- empty_count
- force_unwrapping
Шаг 5: Кэширование зависимостей SPM (ускорение в 2-3 раза)
Каждый раз скачивать зависимости — долго. Кэшируем их:
- name: Cache SPM
uses: actions/cache@v3
with:
path: .build
key: ${{ runner.os }}-spm-${{ hashFiles('Package.resolved') }}
restore-keys: |
${{ runner.os }}-spm-
Вставьте этот шаг перед swift build. Теперь повторные сборки будут летать.
Шаг 6: Продвинутый CI/CD pipeline для Swift — деплой на сервер
Допустим, у вас серверное приложение на Vapor. После успешных тестов и линтинга можно автоматически деплоить на удалённый сервер через SSH:
deploy:
needs: [build-and-test, lint]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Setup Swift
uses: swift-actions/setup-swift@v1
with:
swift-version: "5.9"
- name: Build release
run: swift build -c release
- name: Deploy via S