Автоматизируем iOS-сборку c помощью Jenkins

от автора

Всем привет! Меня зовут Иван Чечиков, я QA-инженер в МТС Digital, работаю в проекте WASD.TV. В этой статье я расскажу о своем способе автоматизации iOS-сборки в TestFlight через Jenkins. С помощью такого метода можно настроить автоматизацию как локально, так и на удаленной машине. Поможет в этом Jenkins – это простой в использовании CI/CD-инструмент. Я рассмотрю локальное применение Jenkins.

 Подробности – под катом.

AppleDeveloper

Нам необходимо быть зарегистрированным в apple developer program и иметь доступ к профилям.

Добавляем новый профиль для дистрибуции:

Выбираем App ID:

Далее генерируем и скачиваем профиль.

Xcode

Нам потребуется Xcode последней версии, устанавливаем его из AppStore. После установки авторизуемся в Xcode:

Выбираем учетку, у которой есть доступ к созданному ранее Provisioning Profile и кликаем на Manage Certificates. Сертификат Apple Distribution должен сгенерироваться и попасть в связку ключей на нашей машине..

Jenkins

Jenkins устанавливаем отсюда. После установки создаем аккаунт и авторизуемся:

Далее отправляемся в Управление плагинами и добавляем плагин SCM:

В Конфигурации системы в Jenkins Location указываем url http://127.0.0.1/

Теперь мы можем создать новый Item — Pipeline

Переходим к настройкам нашего Pipeline

У нас будет параметризованная сборка. Добавляем строковые параметры:

BRANCH – это наша рабочая ветка в Git, на которой мы будем билдить проект. По дефолту указываем свою ветку, либо оставляем поле пустым.

Создаем следущий строковой параметр – BUILD_NUMBER. Это наш номер сборки в TestFlight.

VERSION – версия сборки в TestFlight.

Потом добавляем адрес репозитория в Git и данные для авторизации – логин и пароль. В Branch Specifier указываем наш строковой параметр BRANCH.

Основная логика билда будет лежать у нас в Jenkinsfile. Сохраняем настройки.

Jenkinsfile

Jenkinsfile нужно создать в нашем Git репозитории в ветке, которую мы будем билдить. Он будет выглядеть так:

#!/usr/bin/env groovy pipeline {     agent any     parameters {     string(name: 'BUILD_NUMBER', defaultValue: '', description: 'Номер сборки в TestFlight')     string(name: 'VERSION', defaultValue: '', description: 'Версия сборки в TestFlight')   }     stages {        stage('Install dependencies') {        steps {        sh '''             xcodegen generate             pod install             brew install fastlane            '''        }             }        stage('Pre-build') {        steps {        sh """             agvtool new-version -all ${params.BUILD_NUMBER}             agvtool new-marketing-version ${params.VERSION}             echo \"PROVISIONING_PROFILE_SPECIFIER=Ваш Provisioning Profile\" >> ConfigFile.xcconfig             fastlane spaceauth -u Аккаунт_в_Apple_Developer             echo n              """        }     }        stage('Build') {        steps {        sh '''             xcodebuild -workspace file.xcworkspace -scheme Схема_проекта -configuration Конфигурация_проекта DEVELOPMENT_TEAM=Идентификатор_команды_разработки CODE_SIGN_STYLE=Manual CODE_SIGN_IDENTITY='Apple Distribution' CONFIGURATION_BUILD_DIR=Путь_где_будет_сохранен_билд -archivePath Путь_где_будет_сохранен_архив archive                    xcodebuild -exportArchive -archivePath Путь_где_был_сохранен_архив -exportPath Путь_где_будем_сохранять_файл_ipa -exportOptionsPlist exportOptions.plist            '''        }     }        stage('Send build to TestFlight') {        steps {        sh """           cd Переходим_в_место_где_сохранен_ipa_файл             fastlane pilot upload --changelog "Something that is new here" -u Аккаунт_в_Apple_Developer              """        }     }   } } 

По порядку:

parameters {     string(name: 'BUILD_NUMBER', defaultValue: '', description: 'Номер сборки в TestFlight')     string(name: 'VERSION', defaultValue: '', description: 'Версия сборки в TestFlight')   }

В параметрах указываем номер билда и версию проекта. Наши строковые параметры в Jenkins, которые мы введем в начале сборки, будут подставлены в конфигурационные файлы проекта командами:

agvtool new-version -all ${params.BUILD_NUMBER} agvtool new-marketing-version ${params.VERSION}

Так мы заполняем данные поля для сборки в TestFlight.

На этапе:

stage('Install dependencies') { steps {        sh '''             xcodegen generate             pod install             brew install fastlane           '''         }    }

Генерируем файл проекта .xcodeproj, устанавливаем pod и fastlane библиотеки после клонирования проекта с Git.

stage('Pre-build') { steps {        sh """             agvtool new-version -all ${params.BUILD_NUMBER}             agvtool new-marketing-version ${params.VERSION}             echo \"PROVISIONING_PROFILE_SPECIFIER=Ваш Provisioning Profile\" >> ConfigFile.xcconfig             fastlane spaceauth -u Аккаунт_в_Apple_Developer             echo n           """         }  }

Здесь мы проставляем номер билда и версию проекта. Также хардкодим значение PROVISIONING_PROFILE_SPECIFIER в конфигурационном файле (к примеру, Dev.xcconfig), так как после генерации xcodeproj файла проекта в настройках Xcode по дефолту проставляется Automatic Signing-режим для сборки проекта. Нам это не нужно, у нас режим Manual. Далее авторизуемся в Fastlane и отказываемся от сохранения сессии в cookie.

stage('Build') { steps {        sh '''             xcodebuild -workspace file.xcworkspace -scheme Схема_проекта -configuration Конфигурация_проекта DEVELOPMENT_TEAM=Идентификатор_команды_разработки CODE_SIGN_STYLE=Manual CODE_SIGN_IDENTITY='Apple Distribution' CONFIGURATION_BUILD_DIR=Путь_где_будет_сохранен_билд -archivePath Путь_где_будет_сохранен_архив archive                    xcodebuild -exportArchive -archivePath Путь_где_был_сохранен_архив -exportPath Путь_где_будет_сохранен_файл_ipa -exportOptionsPlist exportOptions.plist           '''         }      }

Билдим проект, сохраняем его в архиве и экспортируем в .ipa файл. Файл exportOptions.plist имеет следущий вид:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>method</key> <string>app-store</string> <key>provisioningProfiles</key>         <dict>         <key>Ваш Bundle Identifier</key>         <string>Ваш Provisioning Profile</string>         </dict> </dict> </plist>
stage('Send build to TestFlight') { steps {        sh """           cd Переходим_в_место_где_сохранен_ipa_файл             fastlane pilot upload --changelog "Something that is new here" -u Аккаунт_в_Apple_Developer           """         }      }

В итоге отправляем сборку в TestFlight. Это длительный процесс, который может занять примерно 30-40 минут.

Пушим Jenkinsfile в репозиторий, переходим в Jenkins и запускаем билд.

Должен получиться вот такой сценарий:

Сборка в TestFlight

Спасибо большое за уделенное время.


ссылка на оригинал статьи https://habr.com/ru/company/ru_mts/blog/659529/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *