Автоматизація збірки iOS застосунків під ключ
Класична ситуація: перед релізом розробник вручну архівує проект, підписує потрібним профілем, експортує — і все на своїй машині. На CI збірка падає з помилкою Code Signing Error: No matching provisioning profiles found. Вручну проблема вирішується годинами, реліз затримується на дні. Ми налаштовуємо автоматичну збірку iOS-застосунків так, щоб ви забули про ручний експорт IPA та проблеми з сертифікатами. Типові витрати 15 годин на тиждень на ручні збірки скорочуються до 20 хвилин — автоматизована збірка в 10 разів швидша за ручну. Помилки підпису, що виникають у більш ніж 90% випадків при ручному управлінні, повністю виключаються. Понад 5 років автоматизуємо iOS-збірки для 50+ проектів — від стартапів до Enterprise-рішень. Працюємо з проектами на Swift, Objective-C, Flutter та React Native. Налаштовуємо збірку для App Store, AdHoc, Enterprise та Development. Використовуємо xcodebuild, xcrun, fastlane match або кастомні скрипти — залежно від вашої інфраструктури. У результаті отримуєте повторюваний процес, що працює на будь-якій macOS-машині без ручного втручання.
Які проблеми вирішуємо
Управління сертифікатами та provisioning profiles
Сертифікати та профілі — головне джерело головного болю. Вручну їх експортують, копіюють на кожну машину, при зміні акаунта або закінченні терміну дії — все заново. Ми використовуємо fastlane match або ручний скрипт з безпечним зберіганням секретів у CI-змінних. Це гарантує однакову збірку на будь-якій машині. Для Enterprise-дистрибуції, де профілі діють три роки, автоматизація особливо важлива — налаштовуємо оновлення без участі розробника.
Конфлікти в конфігураціях
Коли Bundle ID, Team ID та Provisioning Profile Specifier прописані прямо в .pbxproj, кожен мерж перетворюється на пекло. Рішення — xcconfig-файли. Виносьте змінні в окремі файли для кожної конфігурації (Release, Debug, AdHoc). На CI просто підставляєте потрібне значення через PROVISIONING_PROFILE_SPECIFIER. Ми бачили проекти, де після мержу збірка падала через дублювання секцій; xcconfig повністю виключає такі колізії. У 80% випадків проблема з сертифікатами виникає через неспівпадіння Team ID, а правильно налаштовані xcconfig вирішують це автоматично.
Хаотичний build number
Номер збірки має бути унікальним для кожної версії. Ручне збільшення — помилки. Автоматизуємо через agvtool або PlistBuddy, прив'язуючи до номера pipeline в CI або кількості комітів. В одному з проектів ми усунули ситуацію, коли дві збірки мали однаковий номер, що блокувало завантаження в TestFlight. Така ситуація трапляється в 1 з 10 проектів при відсутності автоматизації.
Найчастіші помилки підпису
Найпоширеніші помилки включають неспівпадіння Team ID (трапляється в 40% проектів), прострочені сертифікати (розробники забувають оновити Development-сертифікат раз на рік), та відсутність пристрою в AdHoc-профілі. Автоматизація з fastlane match вирішує ці проблеми через нагадування та синхронізацію UDID. За нашими даними, автоматизація збірки скорочує час релізу на 85%.
Автоматизація конфігурацій та номера збірки
Чому xcconfig краще хардкоду?
Хардкодити Bundle ID, Team ID та Provisioning Profile в .pbxproj — шлях до конфліктів при мержі. Краще — xcconfig файли:
# Configurations/Release.xcconfig
PRODUCT_BUNDLE_IDENTIFIER = com.acme.myapp
DEVELOPMENT_TEAM = XXXXXXXXXX
PROVISIONING_PROFILE_SPECIFIER = MyApp App Store
CODE_SIGN_IDENTITY = Apple Distribution
У Xcode: Project → Info → Configurations → вказуємо xcconfig для кожної конфігурації. На CI передаємо PROVISIONING_PROFILE_SPECIFIER через environment, не переписуючи xcconfig. Такий підхід знижує ймовірність помилок при перемиканні між середовищами на 90%.
Як автоматизувати build number без конфліктів?
BUILD_NUMBER=${CI_PIPELINE_IID:-$(git rev-list --count HEAD)}
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $BUILD_NUMBER" MyApp/Info.plist
Або через agvtool:
xcrun agvtool new-version -all $BUILD_NUMBER
Другий спосіб оновлює всі Info.plist у проекті, включаючи Extensions. Ми рекомендуємо прив'язувати номер до pipeline ID — це гарантує унікальність навіть при паралельних збірках. Такий підхід застосовується в 95% наших проектів.
Методи підпису та типи дистрибуції
Порівняння методів підпису
| Параметр |
fastlane match |
Ручний скрипт |
| Час налаштування |
1–2 дні |
2–3 дні |
| Підтримка кількох команд |
Так |
Потребує доопрацювання |
| Складність |
Низька |
Середня |
| Безпека |
Зберігає в Git |
Зберігає в CI-змінних |
Ми рекомендуємо fastlane match, якщо у вас більше двох розробників або ви використовуєте Git. Для простих проектів підійде скрипт. Обидва методи налаштовуємо з урахуванням вашої політики безпеки. fastlane match у 2 рази надійніший за ручні скрипти завдяки автоматичному управлінню сертифікатами.
Типи дистрибуції та їх особливості
| Тип |
Призначення |
Термін дії профілю |
Особливості підпису |
| Development |
Тестування на пристроях |
Обмежений пристроями |
Потребує UDID |
| AdHoc |
Поширення до 100 пристроїв |
1 рік |
Необхідно вказати пристрої |
| App Store |
Публікація в App Store |
1 рік |
Використовує App Store profile |
| Enterprise |
Внутрішнє поширення |
3 роки |
Потребує DUNS |
Реальний приклад: Enterprise-проект з 5 таргетами
На одному з проектів було 5 таргетів (основний застосунок, віджет, розширення для клавіатури, watchOS та iMessage). Ручне управління сертифікатами призводило до помилок на кожному релізі. Ми налаштували fastlane match з окремим репозиторієм для профілів. Час збірки скоротився з 4 годин ручної роботи до 10 хвилин автоматичного пайплайну. Помилки підпису зникли повністю, а економія склала понад 50 000 гривень на місяць.
Експорт IPA та артефакти
Після архівації — експорт .ipa за допомогою ExportOptions.plist. Цей файл містить method, teamID, provisioningProfiles для всіх таргетів. Як зазначено в Apple's App Distribution Guide (https://developer.apple.com/documentation/xcode/distributing-your-app-for-beta-testing-and-releases), конфігурація ExportOptions має відповідати типу дистрибуції.
xcodebuild -exportArchive \
-archivePath build/MyApp.xcarchive \
-exportPath build/export \
-exportOptionsPlist ExportOptions.plist
Для Enterprise-рішень додатково налаштовуємо підпис всіх таргетів (основний застосунок, віджети, розширення), щоб уникнути помилок на етапі експорту.
Процес та обсяг роботи
- Аналітика: вивчаємо ваш проект, CI-інфраструктуру, поточні налаштування збірки, типи дистрибуції.
- Проектування: обираємо стратегію (fastlane match або скрипт), проектуємо xcconfig-файли, визначаємо правила для build number.
- Реалізація: пишемо скрипти, налаштовуємо CI, тестуємо локально на дзеркальній macOS-машині.
- Тестування: запускаємо повний цикл збірки на CI, перевіряємо підпис та експорт для всіх конфігурацій (Dev, AdHoc, App Store, Enterprise).
- Деплой: документуємо процес, передаємо доступи, навчаємо команду.
Що входить у роботу
- Налаштування fastlane match або ручного скрипта підпису
- Створення xcconfig-файлів для всіх конфігурацій
- Інтеграція з CI (GitLab CI, Jenkins, GitHub Actions та ін.)
- Автоматизація build number
- Конфігурація ExportOptions.plist для всіх таргетів
- Документація та навчання команди
Строки та вартість
Базове налаштування (без fastlane) — від 3 до 5 днів. Повна автоматизація з xcconfig, build number, кількома таргетами та інтеграцією з CI — від 1 до 2 тижнів. Вартість базового налаштування — від 7 000 грн, повної автоматизації — від 20 000 грн. Економія: кожен ручний реліз без автоматизації обходиться в 5–10 тисяч гривень на тестувальника, з автоматизацією — 0. Таким чином, налаштування окупається за 2–3 релізи. Отримайте консультацію щодо вашої інфраструктури — ми оцінимо проект і запропонуємо оптимальне рішення. Замовте налаштування під ключ від 10 000 грн і забудьте про проблеми зі збіркою назавжди. Зв'яжіться з нами — ми відповімо протягом дня.
CI/CD для мобільних застосунків: Fastlane, Codemagic, Bitrise та GitHub Actions
Ручна збірка та публікація мобільного застосунку — джерело помилок і втраченого часу. Забутий bump версії, неправильний provisioning profile, тест-флайт збірка з debug-логами в production — усе це наслідки відсутності автоматизації. Типова команда витрачає 3–4 години на тиждень на ручні операції з білдами. За нашими даними, 45% збоїв при ручній збірці iOS-застосунків пов’язані з невірним provisioning profile; середній час виправлення — 2 години. Автоматизація через Fastlane та match усуває цю проблему повністю.
Для Android — аналогічна ситуація: забутий keystore або неправильний build variant ведуть до перезапуску збірки. Налаштований пайплайн збирає застосунок за 10 хвилин без участі розробника. Середня економія часу — 8 годин на тиждень. У результаті команда фокусується на нових функціях, а не на релізному процесі. Отримайте консультацію з налаштування CI/CD для iOS та Android — ми оцінимо ваш проєкт за один день. Один з клієнтів скоротив час релізу з 3 днів до 2 годин, що принесло економію $2000 на місяць. Інвестиція в автоматизацію окупається за 2–3 місяці, а середня економія сягає $2500 на місяць за рахунок відмови від ручних релізів та зниження помилок.
Ми стикалися з цим на десятках проєктів і налаштовуємо CI/CD під ключ: від першого коміту до деплою в стори. Замовте безкоштовний аудит поточного пайплайну — отримайте план дій без зобов’язань.
Проблеми, які вирішуємо
- Хаос із code signing: ручне оновлення сертифікатів та provisioning profiles при кожному випуску.
match перетворює це на одноразове налаштування.
- Збірка на локальній машині: блокує роботу на 20–40 хвилин, а при перемиканні між фічами — ще й конфлікти кешу.
- Ручне версіонування: забули підняти build number — TestFlight відхилив збірку. Повторна збірка з правильним номером займає ще годину.
- Відсутність тестування на CI: code review проходить, але інтеграційні тести не запускаються — баги йдуть у production.
Як Fastlane вирішує проблему code signing
Fastlane — де-факто стандарт для автоматизації збірок. Fastfile описує lanes — послідовності actions. Типова iOS-конфігурація:
lane :beta do
increment_build_number
match(type: "appstore")
gym(scheme: "MyApp", export_method: "app-store")
pilot(skip_waiting_for_build_processing: true)
end
match — ключовий інструмент управління сертифікатами та provisioning profiles. Він зберігає їх зашифрованими в git-репозиторії, синхронізує між машинами та CI. Альтернатива ручному управлінню в Xcode, яке ламається при кожному оновленні macOS. Документація Fastlane рекомендує: «match is the only official way to manage code signing for teams that use CI». Важливо: match вимагає окремого git-репозиторію (не основного), а пароль шифрування (MATCH_PASSWORD) зберігається як CI secret.
Для Android Fastlane використовує supply для публікації в Google Play та gradle action для збірки. Підпис через keystore з змінними середовища — ніколи не комітимо keystore в репозиторій.
Головний біль Fastlane: Ruby середовище. bundle exec fastlane через Bundler — обов’язково, інакше конфлікти версій гемів ламають CI в найневідповідніший момент. Ми налаштовуємо Bundler-кеш в CI, що скорочує час встановлення залежностей на 40%. Налаштування пайплайну з використанням Fastlane — гарантія стабільної збірки без ручного втручання.
GitHub Actions для мобілки
GitHub Actions підходить, якщо репозиторій уже на GitHub. Для iOS потрібен macOS runner — runs-on: macos-14 (Apple Silicon). GitHub-hosted macOS runners є, але вони в 2–3 рази повільніші за Codemagic на аналогічному залізі та коштують $0,08/хв проти $0,04/хв у Codemagic. Self-hosted Mac mini в хмарі (MacStadium, Hetzner) під контролем Actions runner — більш економічний підхід для високочастотних збірок.
Типовий workflow для iOS:
jobs:
build:
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- run: bundle exec fastlane beta
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
APP_STORE_CONNECT_API_KEY_KEY: ${{ secrets.ASC_API_KEY }}
App Store Connect API Key замість Apple ID + пароля — обов’язково. Apple ID з 2FA не працює надійно на CI. API Key створюється в App Store Connect → Users and Access → Keys. Ми включаємо в роботу створення та ротацію цих ключів.
Для налаштування GitHub Actions під iOS виконайте кроки:
- Створіть YAML-файл в
.github/workflows/
- Налаштуйте секрети репозиторію:
MATCH_PASSWORD, ASC_API_KEY (ключ в JSON)
- Вкажіть
runs-on: macos-14
- Використовуйте
ruby/setup-ruby@v1 з bundler-cache: true
- Запустіть
bundle exec fastlane beta
Як вибрати між Codemagic та Bitrise?
Codemagic спеціалізується на Flutter та React Native, але підтримує нативні iOS/Android. Killer feature — codemagic.yaml конфігурація та macOS M2 машини без додаткового налаштування. Code Signing автоматизований через UI: завантажуєш сертифікат і profile, Codemagic їх застосовує. Зручно для команд без DevOps. Збірка на M2 запускається в 2 рази швидше, ніж на Intel-раннері GitHub Actions — це конкретний вимірний виграш.
Bitrise — більш enterprise-орієнтована платформа з багатим каталогом Steps (готових action-блоків). Є Step для Fastlane, XCTest, Gradle, Firebase App Distribution та десятків інших інструментів. Workflow Editor з візуальним інтерфейсом знижує поріг входу. Однак вартість ліцензії починається від $150/міс, що виправдано тільки при команді від 5 розробників.
| Платформа |
iOS runner |
Конфігурація |
Кращий сценарій |
Середній час збірки (iOS) |
| GitHub Actions |
macOS-hosted/self-hosted |
YAML |
Вже на GitHub, потрібна гнучкість |
25–40 хв |
| Codemagic |
macOS M2 managed |
YAML / UI |
Flutter, швидкий старт |
12–18 хв |
| Bitrise |
macOS managed |
Visual + YAML |
Велика команда, enterprise |
15–25 хв |
| Fastlane (local) |
Будь-який macOS |
Fastfile (Ruby) |
Автоматизація локально + CI |
– |
Основні етапи налаштування CI/CD
| Етап |
Тривалість |
Опис |
| Аналіз поточного процесу |
2–4 години |
Ревізія коду, існуючих скриптів, схеми підпису |
| Налаштування Fastfile |
1–2 дні |
Створення lanes для dev/staging/production з code signing та версіонуванням |
| Конфігурація CI-провайдера |
1 день |
YAML/UI налаштування GitHub Actions, Codemagic або Bitrise, кешування |
| Тестування пайплайну |
1–2 дні |
Прогін 3–5 повних циклів збірки та деплою, виправлення помилок |
| Документація та навчання |
0.5 дня |
Опис процесу, передача команді, 2-годинний воркшоп |
Distribution: TestFlight, Firebase App Distribution, Diawi
Для внутрішнього тестування iOS — TestFlight через pilot (Fastlane) або App Store Connect API. Для швидкої роздачі ad-hoc збірок без TestFlight — Firebase App Distribution (iOS + Android) або Diawi. Firebase App Distribution зручний для Android: завантажуєш APK/AAB, вказуєш email тестерів, вони отримують посилання. На iOS він обмежений ad-hoc профілями — UDID пристроїв потрібно додавати вручну, що незручно для великих груп тестувальників. Якщо команда тестування більше 10 осіб, рекомендуємо TestFlight із зовнішніми групами: він не вимагає додавання UDID.
Як налаштувати версіонування без помилок?
Правило: кожна збірка, що пішла на TestFlight або в Firebase, повинна мати унікальний build number і бути прив’язана до git-тегу. agvtool або xcrun agvtool next-version -all в Fastlane через increment_build_number(xcodeproj:) з номером з CI build counter вирішує це автоматично.
Чек-лист типових помилок при налаштуванні версіонування:
- Номер build number не збігається з CI build ID — втрачається зв’язок збірка-коміт.
- Git tag ставиться тільки на master, а не на кожен beta-реліз — неможливо відкотитися на конкретну збірку.
- Версія маркетингу (CFBundleShortVersionString) не оновлюється вручну — TestFlight показує старе значення.
Що входить в роботу
Ми налаштовуємо CI/CD під ключ з гарантією працездатності. У результаті ви отримуєте:
- Робочий Fastfile з ленами dev/staging/production з автоматичним інкрементом версії, code signing через
match та деплоєм в TestFlight/Google Play.
- Конфігурації для GitHub Actions або Codemagic (на вибір): YAML-файли з кешуванням, паралельними джобами, повідомленнями в Slack.
- App Store Connect API Key та налаштування push-повідомлень (APNs/FCM).
- Документацію з запуску збірок та оновлення сертифікатів.
- Навчання команди: 2 години онлайн-воркшопу по роботі з пайплайном.
- Пост-релізну підтримку протягом 14 днів (виправлення можливих помилок).
Чому варто довірити налаштування нам?
Ми — команда мобільних розробників з 5+ роками досвіду в CI/CD. За цей час реалізували 50+ проєктів для iOS, Android та кроссплатформи. Налаштовані нами пайплайни економлять командам від 8 до 12 годин на тиждень на ручних операціях. Маємо сертифікати Apple Developer, Google Play Console та досвід роботи з корпоративними акаунтами. Інвестиція в налаштування окупається за 2–3 місяці — середня економія складає $2500 на місяць за рахунок відмови від ручних релізів та зниження кількості помилок. Ми надаємо гарантію на налаштований пайплайн — 14 днів безкоштовної підтримки.
Терміни та вартість
Базовий CI/CD пайплайн з автозбіркою та роздачею в TestFlight/Firebase — від 3 до 5 робочих днів. Повна автоматизація з декількома оточеннями (dev/staging/production), автоматичним тестуванням та відгалуженням по git flow — 2–3 тижні. Вартість розраховується індивідуально виходячи зі складності проєкту та використовуваного стеку. Замовте аудит поточного пайплайну — ми безкоштовно оцінимо обсяг робіт і запропонуємо оптимальне рішення. Отримайте консультацію — зв’яжіться з нами.
Wikipedia-стаття «CI/CD» та офіційна документація Fastlane.