[Из песочницы] Сборка билдов Unity3D на Jenkins в Mac OS X. Часть 1

Предыстория


Есть проект на Unity3D. Есть уже несколько лет (родился в феврале 2012 года). Через полгода я начала работать на нем программистом, а через два года мне не повезло и я стала ответственной за сборку билдов. В наследство мне достался MacMini с установленным сборщиком Jenkins, минимум документации и отсутствие адекватной сборки для iOS.

Хочется наконец написать адекватную инструкцию — ибо на первоначальную настройку было убито несколько недель, а при переносе на iMac мои старые наработки уже устарели. Итак…

Техническое задание


  1. Проект разрабатывается на движке Unity3D. Тк разработка продолжалась длительное время, то версия движка успела смениться с 3.5.6 до 4.6.6 (на момент написания статьи поддержки 5 версии пока не планируется). У каждой версии есть свои глюки, некоторые версии содержат жизненно важные правки для одной платформы и в то же время убивают сборку на другой. К примеру — в последних версиях добавлена поддержка 64b для iOS, в ранних 4.x версиях существовала сборка под плагин Google Chrome и Flash, от версии к версии меняется рекомендуемый Android SDK. Нужно иметь все.
  2. Проект находится на svn сервере. Конкретно — subversion.assembla.com. Нужна поддержка сборки из разных веток, различных подпроектов, а также проектов, включающих части других проектов.
  3. Сборка должна осуществляться для Android (Google Play, Amazon App Store, Yandex Store ...), iOS, Windows, Mac OS, Linux (все — с возможностью публикации в Steam). Некоторые части — собираться для запуска в браузере. Здесь рассмотрим только особенности сборки под каждую конфигурацию.
  4. Нужен доступ к билдам из локальной сети, чтобы тестировщик мог скачать, установить и протестировать.
  5. Автономная сборка, автозапуск после сбоя (отключение питания)


Железо


Почему собираем на яблочной продукции? Потому что надо собирать iOS приложения и отправлять их в AppStore. Иметь хакинтош или виртуалку — иметь проблемы.

Итак, есть старенький MacMini в офисе и новейший iMac дома. Оба справляются со своей работой, разница в производительности и подходе — на первый отсутствует гарантия и его не жалко (желание убить его об стол возникает каждую неделю), второй — любовно протирается тряпочкой и бережется.

Итак, для желающих — ознакомиться со сборкой и разборкой первого девайса — добро пожаловать сюда. Потребность в сборке возникла после смерти старого диска. Благодаря инструкции — успешно вскрыт и вставлен новый диск на 1 ТБ.

Здесь стоит сделать отступление — я предпочитаю иметь жесткий диск с несколькими разделами, а возможно даже и с несколькими операционками. Однако, если тип накопителя Fusion Drive — сделать это не получится (мой iMac имеет на диске максимум — два раздела, и на втором обитается Windows). Если диск обычный — проблем никаких. Можно хранить все важные данные в одном разделе (и бэкапить его с помощью Time Machine), а тяжеловесные копии проекта хранить на другом.

Установка системы


Заслуживает отдельной статьи. Кратко:

  1. На новейших маках есть интернет-установка. Иначе — нужен дисковод или флешка с образом системы. Вход в меню установки Cmd+R.
  2. Все диски и разделы обзываем понятными именами. Разделы с системой и рабочими данными форматируем обязательно в Mac OS Extended (Journaled). Обязательно — не Case-sentive.
  3. Для установки софта потребуется Apple Id. Желательно, чтобы этот Apple Id соответствовал аккаунту разработчика Apple, который используется при подготовке и заливке билдов.
  4. Помимо аккаунта администратора необъодим аккаунт с обычными правами. Называем его jenkins, паролим также.
  5. Если кто-то нуждается в удаленном доступе через Chrome Remote Desktop — придется предоставить аккаунту права администратора.
  6. Ставим нормальный браузер и полезный софт по желанию.
  7. Если возникли проблемы с отображением страниц — Steam Community, YouTube и других — смотрим раз и два.


Установка Xcode


  1. Последняя версия обычно ставится из магазина.
  2. При установке нескольких версий — желательно выделить отдельную папку и ставить туда. К примеру — в /Applications/Xcode лежат Xcode_5_1_1.app и Xcode_6_1_1.app.
  3. Старые версии можно найти здесь.


Установка Unity3D


Движок можно скачать на оффсайте (нужна Mac версия) версия или на любимом трекере. На оффсайте регистрируемся и приобретаем нужную лицензию, в зависимости от нужд проекта.

По умолчанию после установки Unity.app, MonoDevelop.app и документация лежат в /Applications/Unity. Если требуется установить несколько версий — сначала переименовываем старую папку установки, к примеру /Applications/Unity_4_6_6_f2, только после этого ставим новую версию и переименовываем место установки тоже. Все версии и патчи можно найти здесь.

MonoDevelop достаточно оставить самый свежий, прописав в настройках каждой Unity путь. В папке /Users/Shared можно обнаружить дефолтный проект Unity — его можно снести.

Для пользователя jenkins необходимо проставить права на запуск всех файлов. При необходимости — и на все содержимое .app.

Также в настройках отключаем автооткрытие последнего проекта и регистрируем каждую копию.

Установка Java, JDK, Android SDK


JDK и JRE можно скачать с оффсайта. Android SDK качаем отсюда. После установки — обновляем SDK и прописываем в каждой Unity путь до него и проверяем на тестовой сборке. Пример работающей конфигурации:

  • OS X 10.10.5
  • Unity 4.6.6f2
  • jdk-8u60-macosx-x64
  • Android SDK: Tools 24.3.4
  • Android SDK: Platform-tools 23.0.1
  • Android SDK: Build-tools 23.0.1
  • Android SDK: SDK Platform API 23


Конфигурация подбирается только опытным путем. Нет никакой гарантии, что при обновлении одного из этих компонентов сборка билдов не упадет…

Установка SVN


Согласно этому — subversion поставляется в комплекте с системой. Для установки специфической версии — рекомендую использовать Homebrew, подробнее ищем здесь.

Установка Jenkins


  1. Все операции выполняем под пользователем jenkins
  2. Качаем с оффсайта установщик. Ставим, переносим в удобное место, к примеру в/Users/jenkins/WORK/JENKINS_WAR/jenkins.war
  3. Заходим в терминал, выполняем команду запуска сборщика:
    java -jar /Users/jenkins/WORK/JENKINS_WAR/jenkins.war
    
    

  4. Проверяем в браузере — 127.0.0.1:8080 наличие сборщика. После закрываем терминал (сборщик отключается)
  5. Создаем папку для временных файлов. К примеру — /Users/jenkins/WORK/JENKINS_TMP
  6. Создаем папку для сборщика. К примеру — /Users/jenkins/WORK/JENKINS_HOME. В нее копируем содержимое папки /Users/jenkins/.jenkins, а саму папку удаляем.
  7. Заходим в терминал и логинимся под администратора:
    login dimamatik
    
    

  8. Удаляем старый файл конфигурации:
    sudo rm /Library/Preferences/org.jenkins-ci.plist
    
    

  9. Заносим следующие параметры (можно поменять, по желанию):
    pp="/Library/Preferences/org.jenkins-ci.plist"
    sudo defaults write $pp JENKINS_HOME "/Users/jenkins/WORK/JENKINS_HOME"
    sudo defaults write $pp tmpdir "/Users/jenkins/WORK/JENKINS_TMP"
    sudo defaults write $pp war "/Users/jenkins/WORK/JENKINS_WAR/jenkins.war"
    sudo defaults write $pp httpPort 4242
    
    

  10. Проверяем:
    defaults read $pp
    
    

  11. Простанавливаем права:
    sudo chown root:wheel $pp
    sudo chmod 644 $pp
    
    

  12. Выгружаем демона дженкинса командой:
    sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist
    
    

  13. Выходим из-под администратора:
    logout
    
    

  14. Запускаем сборщик через терминал еще раз (страница теперь 127.0.0.1:4242). Все должно работать.


Подробнее можно узнать здесь и здесь.

Автозагрузка, перезапуск, смерть


Проблема смерти и реанимации сборщика усугубляется использованием Mac и сборки на Unity. Пишем и сохраняем скрипты:

  • Скрипт запуска сборщика jenkins-runner.sh:
    #!/bin/sh
    "/Library/Application Support/Jenkins/jenkins-runner.sh" &
    
    

  • Скрипт убийства сборщика jenkins-killer.sh:
    #!/bin/sh
    ps xa | grep jenkins.war | grep -v grep | awk '{print $1}' | xargs kill -9
    
    

  • Скрипт перезапуска jenkins-restart.sh:
    #!/bin/bash
    (sh ~jenkins/jenkins-killer.sh) && (sh ~jenkins/jenkins-runner.sh)
    
    


Для автоматического старта сборщика создаем специальное приложение при помощи Automator. Выбираем шаблон Run AppleScript и создаем jenkins-restart.app в той же папке, куда сбросили остальные скрипты. Код программы ниже:

    on run {input, parameters}
    tell application "Terminal"
            activate
            if (the (count of the window) = 0) or (the busy of window 1 = true) then
                tell application "System Events"
                    keystroke "n" using command down
                end tell
            end if
            do script "sh ~jenkins/jenkins-restart.sh"
        end tell
    return input
    end run


В настройках пользователя jenkins ставим автоматический запуск написанного приложения. При желании его можно использовать и вручную. Самого пользователя ставим на автоматический логин при старте системы (если это офисный сборщик, а нам лень приходить пораньше, чтобы его запустить).

Что имеем


На данный момент система должна работать. Сборщик (пока пустой) автоматически запускается при старте системы. Любой проект на Unity должен нормально собираться (руками) из-под пользователя jenkins. При возникновении ошибок — смотрим на разрешения, установленные компоненты, оплачиваем задолжности за лицензию. Самое интересное впереди…

© Habrahabr.ru