Налаштування CI/CD для мобільного додатку через Jenkins
Jenkins обирають, коли потрібен повний контроль над інфраструктурою, уже є on-premise Jenkins-сервер у компанії, або вимоги безпеки забороняють передачу коду в хмарні CI-системи. Для мобільної розробки це означає: Linux-контролер для Android, macOS-агент для iOS.
Архітектура Jenkins для мобільної розробки
Jenkins Controller (Linux/macOS)
├── macOS Agent (для iOS)
│ ├── Xcode 16
│ ├── fastlane
│ └── CocoaPods / SPM
└── Linux Agent (для Android)
├── JDK 17
├── Android SDK
└── Gradle
Агенти підключаються по SSH (Launch agents via SSH) або через JNLP. Для macOS-агента—обов'язково обліковий запис з доступом до Keychain сертифікатів код-підпису.
Jenkinsfile: декларативний pipeline
pipeline {
agent none
environment {
FASTLANE_SKIP_UPDATE_CHECK = 'true'
MATCH_PASSWORD = credentials('match-passphrase')
FIREBASE_TOKEN = credentials('firebase-cli-token')
}
stages {
stage('Test iOS') {
agent { label 'macos-m2' }
steps {
checkout scm
sh 'bundle install --path vendor/bundle'
sh 'bundle exec fastlane test'
}
post {
always {
junit 'fastlane/test_output/report.junit'
}
}
}
stage('Build iOS Beta') {
agent { label 'macos-m2' }
when {
branch 'main'
}
steps {
sh 'bundle exec fastlane beta'
}
}
stage('Build Android') {
agent { label 'linux-android' }
steps {
checkout scm
sh './gradlew test assembleRelease'
archiveArtifacts artifacts: 'app/build/outputs/apk/release/*.apk'
}
}
}
post {
failure {
slackSend(
channel: '#mobile-ci',
color: 'danger',
message: "Build failed: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
)
}
}
}
credentials('match-passphrase')—Jenkins Credentials Store. Секрети не в Jenkinsfile, тільки ID-посилання.
Управління Keychain на macOS-агенті
Головна біль Jenkins + iOS: при запуску як фоновий daemon, codesign не може відкрити Keychain без розблокування. Рішення—розблокування на початку пайплайна:
stage('Unlock Keychain') {
agent { label 'macos-m2' }
environment {
KEYCHAIN_PASSWORD = credentials('macos-keychain-password')
}
steps {
sh 'security unlock-keychain -p $KEYCHAIN_PASSWORD ~/Library/Keychains/login.keychain-db'
sh 'security set-keychain-settings -lut 3600 ~/Library/Keychains/login.keychain-db'
}
}
set-keychain-settings -lut 3600—keychain не блокується 1 годину (достатньо для сборки). Без цього через 5 хвилин простою keychain блокується автоматично та codesign отримує errSecInteractionNotAllowed.
Кешування артефактів
Jenkins не має вбудованого розумного кешу як GitHub Actions. Варіанти:
Спільна директорія на агенті. Папка ~/.gradle або ~/Library/Caches/CocoaPods зберігається між сборками автоматично—якщо завжди використовуватися той же агент (sticky agent).
Jenkins Workspace Caching Plugin. Кешує за хешем Podfile.lock/build.gradle, як GitHub Actions cache.
Artifactory/Nexus. Для enterprise—кеш Maven/Gradle залежностей через внутрішній артифакторій. GRADLE_USER_HOME=~/.gradle + дзеркало Nexus.
Паралельні стадії
stage('Test Parallel') {
parallel {
stage('iOS Tests') {
agent { label 'macos-m2' }
steps { sh 'bundle exec fastlane test' }
}
stage('Android Tests') {
agent { label 'linux-android' }
steps { sh './gradlew test' }
}
}
}
Паралельний прогон iOS та Android тестів скорочує загальний час з ~20 до ~12 хвилин.
Типові проблеми
- xcodebuild не знаходить симулятор—потрібно явно завантажити через xcrun simctl boot "iPhone 16" перед запуском тестів на новому агенті
- Gradle wrapper не знайдений—потрібен chmod +x gradlew на початку кроку
- Build number конфліктує при паралельних сборках—використовуйте ${env.BUILD_NUMBER} як суфікс
Часова шкала
Налаштування Jenkins Pipeline з macOS + Linux агентами, test + deploy lanes: 1–2 тижні (включаючи агентів). Підтримка паралельних сборок, інтеграція Slack/Jira, настройка Artifactory: ще 1 тиждень. Стоимость рассчитывается индивидуально.







