Setting up CI/CD for a mobile application via GitLab CI

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Setting up CI/CD for a mobile application via GitLab CI
Medium
~2-3 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

CI/CD Setup for Mobile Applications via GitLab CI

GitLab CI is optimal for teams already using GitLab repositories (self-hosted or cloud). Configuration in .gitlab-ci.yml, runners—GitLab-managed or self-hosted. For iOS builds you need a registered macOS self-hosted runner: GitLab SaaS provides only Linux/Windows runners in standard plans.

Self-Hosted macOS Runner for iOS

Runner registration:

# On Mac mini or MacBook that will be CI machine
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—runner executes commands directly in shell, without Docker container. For iOS this is the only realistic option, as Xcode doesn't work in Docker.

Important: runner must operate as LaunchDaemon, not user process, otherwise CI stops after Mac reboot. Configure via sudo gitlab-runner install --user runner.

.gitlab-ci.yml Structure for 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 via GitLab CI/CD Variables

GitLab stores secrets in Settings → CI/CD → Variables. For iOS code signing:

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

MATCH_KEYSTORE and MATCH_PASSWORD—masked variables in GitLab. Masked variables don't appear in logs even with echo.

For App Store Connect API Key—File-type variable with .p8 file:

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

Caching

GitLab CI cache is key-based. For CocoaPods:

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

key.files—cache invalidates automatically on Podfile.lock change. For Gradle similarly via .gradle.

Environments and Branch-Based Deploy

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  # Requires confirmation in UI

when: manual for production—click button in GitLab UI as gate before release. Useful when QA must confirm before App Store submission.

Timeline

Basic setup (macOS runner, test + beta lanes): 3–5 days. Full configuration with environments, Android pipeline, caching, review-apps: 1.5–2 weeks. Cost calculated individually.