Автоматизация сборки Flutter-приложения для iOS с использованием macOS
1 часть: Нано-ЦОД на Mac M4 mini

В этой статье рассмотрим настройку автоматической сборки Flutter-приложения для iOS с использованием Fastlane на macOS.
Шаг №0: Подготовка окружения
Для успешной сборки iOS-приложений требуется:
GitLab Runner в варианте
shell executor(сборка в контейнере усложняет работу с Xcode)Xcode - среда разработки, эмулятор и инструменты сборки
Fastlane - инструмент для автоматизации сборки и публикации приложений
Rbenv - менеджер версий Ruby
Установка компонентов
Xcode
Установка через командную строку:
xcode-select --install
Альтернативный способ - установка из AppStore

GitLab Runner
Установка через Homebrew
brew install gitlab-runner
Fastlane и зависимости
Сначала нужно установить Bundler
gem install bundler
А потом сам Fastlane
brew install fastlane
macOS уже содержит системную версию Ruby, но она недостаточна для сборки приложения. Обновление системного Ruby может нарушить работу системы, поэтому используем Rbenv для временного переопределения версии Ruby во время сборки.
Шаг №1: Конфигурация Fastlane
Типовая структура Flutter-проекта:

Для настройки iOS-сборки работаем в каталоге ios/.
Создание конфигурации Fastlane
Создайте папку fastlane в директории ios/ со следующими файлами:
1. Appfile
Appfile конфигурирует основную информацию о приложении
app_identifier("your.flutter.app") # Bundle identifier вашего приложения
apple_id("yourmail@gmail.com") # Ваш Apple ID для Developer Portal
itc_team_id("TEAM123456") # App Store Connect Team ID
team_id("TEAM123456") # Developer Portal Team ID
рабочий пример:

2. Fastfile
Fastfile определяет lanes (задачи) для сборки
default_platform(:ios)
platform :ios do
desc "Push a new beta build to TestFlight"
lane :beta do
# Получаем номер сборки из переменной окружения
build_number = ENV["BUILD_NUMBER"]
puts("Using build number: #{build_number}")
# Сборка приложения
build_app(
workspace: "Runner.xcworkspace",
scheme: "Runner"
)
# Загрузка в TestFlight
upload_to_testflight(
api_key: app_store_connect_api_key(
key_id: "KEY_ID", # Идентификатор ключа из Apple Developer Portal
Issuer_id: "ISSUER_ID", # Идентификатор пользователя, выпустившего ключ
key_filepath: "fastlane/auth.p8" # Путь к файлу с ключом
)
)
end
end
Мы используем немного модифицированный, но приведенный пример также рабочий.

3. auth.p8
Создайте пустой файл auth.p8, который будет заполняться ключом во время выполнения пайплайна.
Шаг №2: Настройка GitLab CI/CD пайплайна
Конфигурация задания сборки
Для сборки мы используем Gitlab CI, а значит дальше работаем с файлом .gitlab-ci.yml
build_ios:
stage: build
tags:
- macos
only:
- dev
script:
- printf "%b" "$AUTHP8" > ./ios/fastlane/auth.p8
- export BUILD_NUMBER=$CI_PIPELINE_IID
- echo "BUILD_NUMBER=$BUILD_NUMBER"
- 'sed -i "" -E "s/^version: ([0-9]+\.[0-9]+\.[0-9]+)\+([0-9]+)/version: 1\.${BUILD_NUMBER}\.0+1/" pubspec.yaml'
- env BUILD_NUMBER=$BUILD_NUMBER /bin/zsh -ilc 'rbenv shell 3.2.2; cd ios; flutter clean; flutter pub get; pod install; pod update; fastlane beta'

Детальное описание скрипта
1. Сохранение ключа авторизации:
printf "%b" "$AUTHP8" > ./ios/fastlane/auth.p8
Ключ хранится в защищенной переменной GitLab AUTHP8 и записывается в файл перед сборкой. Его мы берем с Apple Developer Portal. Обратите внимание, там достаточно большой список настроек, и вам нужно определиться с тем, какой именно ключ вам нужен. Может потребоваться несколько попыток %)

2. Установка номера сборки:
export BUILD_NUMBER=$CI_PIPELINE_IID
Используем ID пайплайна GitLab как номер сборки. нельзя загружать одну и ту же версию - будет отказ.
3. Обновление версии приложения:
sed -i "" -E "s/^version: ([0-9]+\.[0-9]+\.[0-9]+)\+([0-9]+)/version: 1\.${BUILD_NUMBER}\.0+1/" pubspec.yaml
Автоматическое обновление версии в pubspec.yaml по шаблону 1.{BUILD_NUMBER}.0+1.
4. Процесс сборки:
Установка версии Ruby через Rbenv
Очистка предыдущих сборок
Получение зависимостей Flutter и CocoaPods
Запуск сборки через Fastlane
Данная конфигурация обеспечивает надежную автоматическую сборку Flutter-приложений для iOS с интеграцией в GitLab CI/CD.


Можно улучшить сборку, сохранением Cocoa pods в кеше или в артифакт регистри, но это буквально экономия на спичках. Для меня практически отсутствует разница между 7 и 9 минутами сборки приложения ?♂️
Прошлая часть "Нано‑ЦОД на Mac M4 mini" о том как мы пришли к решению развернуть рабочий мини-сервер на Mac Mini: https://habr.com/p/963564/
Оставайтесь на связи с vin.team!
infectedtrauma
Действительно, не обманули. Очень наглядно, спасибо!