Настройка CI/CD для мобильного приложения через GitLab CI

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1735 услуг
Настройка CI/CD для мобильного приложения через GitLab CI
Средний
~2-3 дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    495

Настройка CI/CD для мобильного приложения через GitLab CI

GitLab CI — оптимальный выбор для команд, которые уже держат репозиторий на GitLab (self-hosted или cloud). Конфигурация в .gitlab-ci.yml, раннеры — GitLab-managed или собственные. Для iOS-сборки нужен зарегистрированный macOS self-hosted runner: GitLab SaaS предоставляет только Linux/Windows-раннеры в стандартных планах.

Self-hosted macOS-раннер для iOS

Регистрация раннера:

# На Mac mini или MacBook, который будет CI-машиной
brew install gitlab-runner
gitlab-runner register \
  --url https://gitlab.com \
  --registration-token $RUNNER_TOKEN \
  --executor shell \
  --description "macos-m2-runner"
gitlab-runner start

executor shell — раннер выполняет команды напрямую в shell, без Docker-контейнера. Для iOS это единственный реалистичный вариант, так как Xcode не работает в Docker.

Важно: раннер должен работать как LaunchDaemon, не как пользовательский процесс, иначе при перезагрузке Mac CI останавливается. Настройка через sudo gitlab-runner install --user runner.

Структура .gitlab-ci.yml для iOS + Android

stages:
  - test
  - build
  - distribute

variables:
  FASTLANE_SKIP_UPDATE_CHECK: "true"
  BUNDLE_PATH: vendor/bundle

.ios_job:
  tags:
    - macos-m2
  before_script:
    - bundle install --path $BUNDLE_PATH

.android_job:
  image: androidsdk/android-34
  tags:
    - linux-docker

ios:test:
  extends: .ios_job
  stage: test
  script:
    - bundle exec fastlane test
  artifacts:
    reports:
      junit: fastlane/test_output/report.junit
    paths:
      - fastlane/test_output/
    expire_in: 1 week
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == "main"

ios:beta:
  extends: .ios_job
  stage: distribute
  script:
    - bundle exec fastlane beta
  environment:
    name: beta
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  needs: [ios:test]

android:build:
  extends: .android_job
  stage: build
  script:
    - ./gradlew test assembleRelease
  cache:
    key: $CI_COMMIT_REF_SLUG
    paths:
      - .gradle/
      - vendor/bundle
  artifacts:
    paths:
      - app/build/outputs/apk/release/
    expire_in: 3 days

Code signing через GitLab CI/CD Variables

GitLab хранит секреты в Settings → CI/CD → Variables. Для iOS code signing:

before_script:
  - echo "$MATCH_KEYSTORE" | base64 -d > /tmp/match.keystore
  - bundle exec fastlane match adhoc --readonly true

MATCH_KEYSTORE и MATCH_PASSWORD — masked variables в GitLab. Masked переменные не выводятся в логах даже при echo.

Для App Store Connect API Key — File-тип переменной с .p8-файлом:

- echo "$ASC_API_KEY" > /tmp/AuthKey.p8
- export APP_STORE_CONNECT_API_KEY_PATH=/tmp/AuthKey.p8

Кэширование

GitLab CI кэш привязан к ключу. Для CocoaPods:

cache:
  key:
    files:
      - Podfile.lock
  paths:
    - Pods/
    - vendor/bundle

key.files — кэш инвалидируется автоматически при изменении Podfile.lock. Для Gradle аналогично через *.gradle*.

Environments и деплой по веткам

ios:staging:
  stage: distribute
  script:
    - bundle exec fastlane beta
  environment:
    name: staging
  rules:
    - if: $CI_COMMIT_BRANCH == "develop"

ios:production:
  stage: distribute
  script:
    - bundle exec fastlane release
  environment:
    name: production
  rules:
    - if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
  when: manual  # Требует подтверждения в UI

when: manual для production — нажатие кнопки в GitLab UI как gate перед релизом. Полезно, когда QA должен подтвердить перед отправкой в App Store.

Сроки

Базовая настройка (macOS-раннер, test + beta lanes): 3–5 дней. Полная конфигурация с environments, Android-конвейером, кэшированием, review-apps: 1.5–2 недели. Стоимость рассчитывается индивидуально.