Каждый iOS-разработчик хотя бы раз проходил через это: нужно выложить сборку в TestFlight, а ты полтора часа сидишь и вручную обновляешь сертификаты, пересобираешь архив, ждёшь загрузки, получаешь ошибку от App Store Connect — и начинаешь сначала. Это не разработка, это страдание.
Fastlane решает именно эту проблему. А CI/CD делает так, чтобы вся эта боль вообще не требовала твоего участия.
Что такое Fastlane и зачем он нужен
Fastlane — это набор инструментов командной строки для автоматизации рутины в iOS (и Android) разработке. Его написали на Ruby, и он умеет:
- собирать приложение (
gym)
- управлять сертификатами и provisioning profile (
match)
- загружать сборку в TestFlight и App Store (
pilot, deliver)
- запускать тесты (
scan)
- делать скриншоты для стора (
snapshot)
Без Fastlane типичный релизный цикл выглядит так: открыл Xcode, обновил версию, собрал архив (минут 10-15), открыл Organizer, нажал Distribute, прошёл через пять экранов мастера, подождал загрузки — ещё минут 20. И так каждый раз. Если релизы частые или команда большая — это реальная проблема.
С Fastlane весь процесс сворачивается в одну команду в терминале.
Установка и первичная настройка
Fastlane ставится через Bundler — это правильный способ, который фиксирует версию и не ломает окружение.
Создай Gemfile в корне проекта:
source "https://rubygems.org"
gem "fastlane"
Потом:
bundle install
bundle exec fastlane init
Fastlane спросит, что ты хочешь делать — выбери «Automate beta distribution to TestFlight» или «Manual setup». Для первого знакомства подойдёт автоматический режим, но в реальных проектах лучше настраивать руками — так понимаешь, что происходит.
После инициализации появится папка fastlane/ с двумя файлами:
Appfile — настройки приложения (bundle ID, Apple ID, team ID)
Fastfile — сами сценарии (lanes)
Fastfile: как устроены lanes
Lane — это просто набор действий, которые выполняются последовательно. Вот базовый пример:
default_platform(:ios)
platform :ios do
lane :beta do
increment_build_number
build_app(
scheme: "MyApp",
configuration: "Release",
export_method: "app-store"
)
upload_to_testflight(
skip_waiting_for_build_processing: true
)
end
end
Запускаешь bundle exec fastlane beta — и через несколько минут новая сборка уже в TestFlight.
increment_build_number автоматически поднимает build number, что избавляет от «ой, забыл обновить» перед каждым деплоем.
Match — главная боль с сертификатами
Сертификаты и provisioning profiles — больная тема для любой команды. Один разработчик создал сертификат локально, другой не может собрать проект, третий случайно отозвал чужой профиль. Классика.
Match решает это радикально: все сертификаты хранятся зашифрованными в отдельном git-репозитории (или S3/Google Cloud Storage), а каждый разработчик и CI-сервер скачивает их через единую команду.
Настройка:
bundle exec fastlane match init
Fastlane спросит, где хранить сертификаты. Для команды удобнее всего приватный git-репозиторий. Укажи его URL.
Потом создаёшь сертификаты для нужных окружений:
bundle exec fastlane match appstore
bundle exec fastlane match development
В Fastfile использование match выглядит так:
lane :beta do
match(type: "appstore", readonly: true)
build_app(scheme: "MyApp")
upload_to_testflight
end
Параметр readonly: true важен для CI — он говорит «только скачай существующие, ничего не создавай». Создание сертификатов делается отдельно, вручную, один раз.
Пароль для расшифровки передаётся через переменную окружения MATCH_PASSWORD. Никогда не хардкодь его в Fastfile.
CI/CD: автоматизация без участия человека
Fastlane — это инструмент для локального запуска и для CI. CI/CD (Continuous Integration / Continuous Delivery) — это система, которая запускает твои скрипты автоматически при каждом пуше или по расписанию.
Для iOS-проектов популярны несколько вариантов:
GitHub Actions — бесплатно для открытых репозиториев, для приватных есть лимиты. MacOS-раннеры стоят дороже Linux, но они необходимы для сборки iOS.
Bitrise — специализированный сервис для мобильной разработки. Много готовых шагов для iOS, удобный UI, но платный.
GitLab CI — хорошо подходит, если уже используешь GitLab. Нужен собственный macOS-раннер или платный облачный.
Xcode Cloud — встроенный CI от Apple. Интегрирован в Xcode и App Store Connect, бесплатный тариф есть, но функциональность ограничена.
Пример: GitHub Actions + Fastlane
Создай файл .github/workflows/beta.yml:
name: Beta Deploy
on:
push:
branches:
- main
jobs:
deploy:
runs-on: macos-14
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
- name: Deploy to TestFlight
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.API_KEY_ID }}
APP_STORE_CONNECT_API_ISSUER_ID: ${{ secrets.API_ISSUER_ID }}
APP_STORE_CONNECT_API_KEY_CONTENT: ${{ secrets.API_KEY_CONTENT }}
run: bundle exec fastlane beta
Все секреты — пароли, ключи API — хранятся в настройках репозитория (Settings → Secrets), не в коде.
Для авторизации в App Store Connect лучше использовать API Key вместо логина и пароля — он надёжнее и не ломается от двухфакторной аутентификации. Ключ создаётся в App Store Connect → Users and Access → Keys.
В Fastfile подключаешь его так:
app_store_connect_api_key(
key_id: ENV["APP_STORE_CONNECT_API_KEY_ID"],
issuer_id: ENV["APP_STORE_CONNECT_API_ISSUER_ID"],
key_content: ENV["APP_STORE_CONNECT_API_KEY_CONTENT"]
)
Что ещё умеет Fastlane
Автоматические скриншоты. snapshot запускает UI-тесты на симуляторах разных размеров и делает скриншоты. frameit добавляет к ним рамки устройств. Особенно полезно, когда приложение локализовано — вместо того чтобы вручную делать 5 скриншотов × 6 локалей × 3 устройства = 90 картинок, запускаешь одну команду.
Управление версиями. increment_version_number и increment_build_number можно настроить так, чтобы версия поднималась автоматически по тегу в git.
Уведомления. Fastlane умеет отправлять сообщения в Slack, когда сборка прошла или упала. Добавляется одной строкой:
slack(
message: "Beta успешно задеплоена!",
slack_url: ENV["SLACK_URL"]
)
Прогон тестов. scan запускает тесты и генерирует HTML-отчёт. В CI это выглядит так: пуш в ветку → тесты → если прошли, собираем и деплоим.
Типичные ошибки при настройке
Не используют Bundler. Устанавливают Fastlane глобально через gem install fastlane и потом удивляются, почему на CI другая версия и что-то ломается. Всегда фиксируй версию через Gemfile.
Хранят секреты в Fastfile. Видел это не раз: кто-то закоммитил Apple ID и пароль прямо в репозиторий. Все чувствительные данные — только через переменные окружения.
Не используют readonly: true для match на CI. Если CI попытается создать новый сертификат и не сможет (нет прав), пайплайн упадёт в самый неподходящий момент.
Забывают про xcode-select. На CI нужно явно указывать версию Xcode. Разные версии Xcode могут давать разные результаты сборки. В GitHub Actions это делается через xcode-select -s /Applications/Xcode_15.4.app.
Слишком длинные lanes. Если lane делает 15 вещей подряд, найти проблему сложно. Лучше разбить на маленькие lanes и вызывать одни из других.
Сколько времени это экономит
Конкретные цифры из практики: ручной деплой в TestFlight занимает 20-40 минут активного внимания разработчика. С Fastlane — 2-3 минуты на запуск команды, остальное работает само.
Если деплоить раз в неделю, это около 30 минут экономии. Если два раза в день — несколько часов в неделю. Плюс снижается число ошибок: забытый bump версии, неправильный provisioning profile, не тот scheme — всё это уходит.
Для команды из трёх разработчиков настройка Fastlane + CI занимает примерно день работы. Окупается за месяц.
С чего начать прямо сейчас
Если никогда не пробовал Fastlane — начни с малого. Возьми существующий проект и настрой один lane, который просто собирает приложение и загружает в TestFlight. Без match, без CI — просто локальный запуск.
Когда это заработает и ты поймёшь механику, добавь match. Потом подключи GitHub Actions или другой CI. Не пытайся сразу настроить всё идеально — это путь к тому, что ничего не будет настроено вообще.
Документация Fastlane на docs.fastlane.tools подробная и хорошо структурированная — там есть примеры для большинства типичных сценариев.
Если разрабатываешь мобильное приложение в связке с бэкендом или веб-частью — REEXY занимается и серверной разработкой, и интеграциями, так что автоматизацию можно выстроить сквозную: от коммита до продакшена на всех платформах одновременно.
Автоматизация сборки — это не про сложность. Это про то, чтобы не делать руками то, что машина делает лучше.