Continuous Integration с Unity

  • Tutorial
С переходом на новый проект на Unity с относительно большой командой разработчиков резко встала необходимость автоматической сборки и доставки приложения на устройства для тестирования. Вот как с этим обстояла ситуация, когда я пришел на проект (под iOS):
  1. На отдельной mac-машине проект вручную выкачивался из репозитория (Asset Sever).
  2. Вручную (File->Build Settings->Build & Run) запускалась сборка в xCode-проект.
  3. Далее в xCode делался архив (Archive).
  4. Архив экспортировался в ipa-файл, который вручную загружался в TestFlight.
  5. Далее, уже в TestFlight доступ предоставлялся нужным тестерам.

Все описанное выше автоматизируется с помощью так называемой непрерывной интеграции (англ. Continuous Integration, CI). На моих предыдущих проектах для этих целей использовался TeamCity от JetBrains (создателей удобного инструмента рефакторинга кода Resharper). TeamCity (TC) — очень мощный программный продукт, выполняющий цели, поставленные перед системой непрерывной интеграции, на все 100%. Он умеет даже больше. Но речь в статье пойдет не о нем (о нем уже есть статьи на хабре), а о новом сервисе Unity Cloud Build, специально для разработчиков на движке Unity.

UPD. Unity выпустила Unity Cloud Build в свет, а я обновил статью :) Об изменениях и нововведениях читайте ниже.

Для начала хочу предупредить, что некоторые ссылки ниже требуют доступ к Unity Cloud Build, его форуму и документации.

Проблема


Проект у нас большой, и вся процедура, описанная выше, занимала от получаса и более. Mac, на котором делались сборки, был медленным. Приложение на устройство программисты устанавливали редко (все проверялось, в основном, в редакторе). И поэтому, одного подхода обычно было недостаточно, т.к. после загрузки на устройство в приложении внезапно (по закону подлости) обнаруживались ошибки. К тому же не было нормального QA. В дополнении, все это делалась вечером в пятницу — т.е. получаем все неблагоприятные для такого важного дела условия :)

Понятное дело, что так больше продолжаться не могло. Решение должно было быть, естественно, комплексным, и в качестве одной из его частей я поставил задачу: внедрить в разработку CI. Задача ставилась так:
  • система CI должна быть по возможности бесплатной;
  • должна поддерживать сборку Unity-проектов;
  • её настройка должна быть очень простой;
  • на все про все — не более одного рабочего дня.

В прошлый раз в TeamCity я убил как раз где-то день на настройку первой сборки, но потом еще продолжительное время настраивал и поддерживал эти сборки. К тому же он требует размещения на своем сервере, его настройку и поддержку. А в этот раз я решил попробовать Unity Cloud Build. В последнее время я много о нем слышал и в первую очередь меня купило то, что не нужно иметь свой сервер и mac в качестве машины для сборки, все делается на их стороне.
Unity приобрела платформу Tsugi и на ее базе построила Unity Cloud Build. Сейчас сервис уже в открытом доступе, любой разработчик Unity, даже владелец бесплатной версии, может зарегистрироваться и пользоваться системой на бесплатном плане по умолчанию. Я зарегистрировался в UCB на их странице и принялся настраивать первую сборку.

Настройка


Настройка заняла у меня от силы минут 15. Она интерактивная и проходит в несколько этапов.
  • Ввод ссылки на проект в репозитории. Поддерживается svn, perforce и git. Тип репозитория определяется автоматически по ссылке. Оказалось, что UCB не поддерживает Asset Server, что странно — не поддерживать собственную систему контроля версий. Когда я пришел работать над проектом, он был как раз на AS. При знакомстве с AS, меня убило в первую очередь то, что нет поддержки веток (а для большого проекта это важно), и слияние у них основано на времени изменения (time-based), а не на изменениях. Отсутствие поддержки AS у UCB стало еще одной причиной перевода проекта на git-репозиторий.
  • Настройка доступа к репозиторию. В случае с git UCB генерирует SSH-ключ, который нужно прописать, например, в админке проекта на bitbucket или github. После получения доступа, UCB позволяет выбрать ветку, из которой будет происходить сборка проекта.
  • Настройка проекта. На этом этапе есть возможность выбрать версию Unity, с помощью которой будет происходить сборка проекта. Сейчас у UCB доступны все версии до Unity 5 beta включительно. На данный момент UCB поддерживает платформы Web, iOS и Android, при этом для доступа к ним не обязательно иметь Pro-лицензии для платформ iOS и Android, по крайней мере сейчас;) В будущем планируют добавить Standalone-платформы и Windows Phone. Так же можно указать конкретную папку в репозитории, как папку Unity-проекта.
  • Настройка сборки и подписки приложения. На этом этапе указывается сертификат для подписки приложения в p12-формате. В случае iOS также указывается профиль (provision profile) и можно выбрать версию xCode — 5 или 6 (сейчас используется 6.0.1).

После этого система автоматически начнет сборку проекта. В конце процесса будут доступны компактный и детальный лог сборки, само приложение + запакованный dSYM (для iOS).
UPD. Как оказалось, в случае Android UCB не умеет разбивать apk на expansion-файлы. Так что в этом случае можно использовать UCB только для тестирования, а релизный билд собирать вручную.

Распространение собранного приложения


В UCB есть несколько возможностей “поделиться” сборкой:


  • Collaborators. Это список всех, кто имеет доступ к проекту. По окончанию сборки, каждому из этого списка будет приходить сообщение на почту с ссылкой для установки. Можно перейти по ней на устройстве и установить приложение в одно касание. А можно зайти в админку из браузера на компьютере и скачать ipa-файл и дальше уже делать с ним все, что вздумается. У этого метода есть один недостаток — все из этого списка получают доступ к настройкам сборки и всем собранным приложениям.
  • Share via Link. Генерируется ссылка, по которой можно будет скачать конкретную сборку. По этой ссылке любой может скачать/установить приложение. Она перманентная, т.е. со временем не меняется для конкретной сборки.
  • UPD. Опции Push to TestFlight больше нет. Apple закрыла Testflight в старом виде (перед этим запретив загрузку Android-приложений для тестирования) и предложила на его основе свою версию распространения тестируемых приложений через iTunes Connect. Извращенность нового метода от Apple в том, что чтобы отдать приложение на внешний тест (External Testers, до 1000 тестеров), оно должно пройти внутреннюю проверку — Beta App Review. Сколько она длится — не знаю, еще не пробовал, но приложение должно соответствовать всем тем же критериям, что и перед отправкой в AppStore. Для внутренних тестов (Internal Testers, не больше 25) тестеры должны иметь доступ к iTunes Connect в роли Technical или Admin, а это не всегда возможно.

Другие возможности


  • Кол-во сборок неограниченно. Например, в бесплатном TC есть ограничения на кол-во агентов (так у них называются машины для сборки) и кол-во сборок. На дополнительные нужно покупать доплицензии.
  • Unity Cloud Build manifest. Я узнал о манифесте сборки, когда пытался встроить в debug-сборку возможность отображать в приложении информацию о коммите, из которого приложение было собрано. Это очень удобно при тестировании. Оказалось, что ребята из UCB встраивают в проект некий “манифест” в JSON-формате, из которого можно получить много полезной информации для тестов: коммит, название ветки, номер сборки и пр. Но, если нужно собрать приложение для магазина, этот манифест уйдет вместе с ним в продажу :(

Дополнительные настройки


В настройках есть раздел расширенных настроек (Advanced Settings). Совсем недавно он был доступен только по запросу, в режиме тестирования. Сейчас доступен для держателей платных подписок.
  • Development Builds. Соответствует опциям сборки BuildOptions.Development + BuildOptions.AllowDebugging, и соответствующим настройкам в File->Build Settings, чтобы можно было отлаживать собранное приложение. По умолчанию, собирается Release.
  • Pre/Post-Export Method Name. Эти методы вызываются перед сборкой проекта и после создания xCode-проекта, соответственно. Вот они как раз уже позволяют творить чудеса! Надо заметить, что файл класса для этих методов обязательно должен находиться в папке Editor (не обязательно в корне проекта). Это не указано в справке и отняло у меня время, пока я не добился рабочей сборки.
  • Scripting Define Symbols — очень удобная вещь. Можно не задавать их в настройках проекта, а задать отдельно для каждой сборки. Например, использовать в коде символы препроцессора типа DEBUG, RELEASE, STORE, и тд.
  • Scene List — можно отдельно задать список сцен для сборки. Может пригодиться, например, если для тестов есть особые тестовые сцены.


Подписки и цена


С релизом системы Unity Cloud Build были введены подписки. Есть 4 вида подписок, каждая новая включает в себя предыдущую:
1. Free.
  • Как видно из названия — это бесплатный план.
  • Выделяется 1Gb на проект, при этом считается все место, занимаемое папкой проекта при сборке.
  • Минимум 60 минут между сборками, т.е. до начала следующей сборки (автоматической или ручным запуском) придется подождать минимум час. Но Library Caching включено по умолчанию.
  • Возможность одновременно собирать только 1 проект.
  • Нельзя добавлять других людей к проекту (Collaborators). Зато можно делится сборками с помощью генерируемых на них ссылок (Share via Link).
  • Не доступны расширенные настройки (Advanced Settings).

2. Pro.
  • 25$ в месяц.
  • 2Gb на проект.
  • Минимум 30 минут между сборками.
  • Одновременно можно собирать до 3 проектов.
  • К проекту можно добавить до 5 человек.
  • Дополнительно доступны опции Development Builds и Custom Scripting Defines.

3. Studio.
  • 100$ в месяц.
  • 5Gb на проект.
  • Минимум 5 минут между сборками.
  • Одновременно можно собирать до 6 проектов.
  • К проекту можно добавить до 20 человек.
  • Доступны дополнительно опции Pre-/ Post-Export methods и Custom Scene Lists.
  • Поддержка Perforce.

4. Enterprise.
  • Отдельный план. О цене нужно договариваться.
  • Выделяются отдельные машины для сборки ваших проектов.
  • Теоретически — самое быстрое время сборки проектов.
  • Все ограничения выше сняты.




Недостатки или чего еще хочется


  • Проект собирается относительно долго. Имеется ввиду бесплатная подписка. В ней также есть ограничение в 1 час между сборками. Сейчас проект, который локально собирается за 5-10 мин, на UCB собирается за 15-50 мин. Причина в том, что UCB не позволяют хранить его у себя, и каждый раз он заново загружается из репозитория. Единственная оптимизация, которая есть, это опция Cache Library Directory — позволяет кешировать для проекта папку Library, так что при новой сборке не приходится снова все экспортировать. В целом для разработки это время не столь критично, если у программистов есть возможность собирать проект локально, для своих тестов. В платных планах время между сборками сокращено, а на самом дорогом есть так называемые «выделенные машины для сборки” (Dedicated Build Machines), в которых они обещают очень быструю сборку за счет выделения отдельных машин для компании и кеширования всего проекта на этих машинах. Просьба, отписаться в комментариях, так ли это, если кто-то успел попробовать.
  • Нет возможности настроить сборку из семейства веток, типа feature/*. Такая возможность есть в TC, а UCB всегда собирает из строго указанной ветки. Если кто знаком с парадигмой git-flow, бывает очень полезно для разработки, когда программисты заводят разные ветки на задачи и могут (они или тестеры) тут же протестировать ее на собранном приложении. В итоге мы обошлись несколькими проектами в UCB, настроенными на разные ветки, например, master (Release-сборка отдельно для тестов и загрузки в магазин), develop, ветка из release для непрерывного тестирования текущего выпуска и конкретные ветки текущих фич (feature). Естественно, у этих проектов — разные настройки, такие как Development Build, Scripting Define Symbols. Соответственно, автоматически собирается Release-сборка для тестов и AppStore, как только release-ветка вливается в master (в соответствии с git-flow).
  • Пока нет возможности включить в процесс автоматическое тестирование, хотя Dmytro Mindra на последнем DevGamm в Минске клялся, что такая возможность есть) Естественно, это можно сделать в ручную, через Unity Test Tools и опцию Pre-Export Method, но хочется более серьезной нативной поддержки, с таблицей результатов тестирования и графиками)
  • Не всегда проект, собранный на локальной машине, соответствует тому, что будет собрано на UCB, и не всегда такое приложение будет работать на устройстве. Например, мы использовали плагин для внутриигровых покупок от Soomla. Приложение, собранное локально, работало нормально, а собранное на UCB “вешалось” на функции Initialize плагина. В результате оказалось, что Soomla добавляет флаг `-ObjC` в Build Settings > Other Linker Flags и оно неправильно используется UCB. Проблему уже исправили, но из-за нее мы некоторое время не могли тестировать сборки из UCB, приходилось собирать проект локально, по-старинке).
  • UPD. Нет поддержки Split Application Binary. Если в настройках проекта включен Split Application Binary для получения файла дополнений для Google Play, в случае, когда приложение занимает больше 50Mb, придется его отключить, иначе в UCB на выходе будет нерабочий apk без файла дополнений. Пока поддержка дополнений не реализована.

Резюме


Итак, мне Unity Cloud Build пришелся по душе. Проект развивается, на форуме спрашивают о текущих запросах разработчиков и постепенно их реализуют, техподдержка отвечает довольно быстро. Если вы разрабатываете проекты на Unity и задумались о CI, рекомендую попробовать Unity Cloud Build. Сэкономите время и деньги.

Плюсы:
  • Быстрая настройка. При готовых сертификатах, профилях и ссылке на репозиторий займет всего 2 минуты.
  • Возможность “бесплатно” собирать под Android и iOS, их лицензии не требуют, и даже mac не потребуется.
  • Для тех, кому неважно время сборки, это отличная возможность автоматической сборки и хранения всех сборок приложения.
  • Дополнительные возможности по настройке сборки.
  • Кол-во проектов и сборок неограниченно.

Минусы:
  • Относительно долгое время сборки на бесплатном плане. С самым дорогим планом обещают быструю сборку, но сам не пробовал, не могу гарантировать.
  • Нет поддержки Hg, TFS, Asset Server (хотя последними двумя я не рекомендовал бы пользоваться).
  • Нет встроенной поддержки автоматических тестов.


Жду вопросы, предложения, уточнения в комментариях!

Возможно, кому-то будет интересно почитать мои предыдущие статьи:

Удачи вам в разработке!
Поделиться публикацией
Комментарии 20
    0
    Как вам живется с большим проектом на bitbucket, учитывая количество бинарных ассетов? Нет проблем с размерами репозитория?
      0
      Уже были:) Пока вырезали из истории удаленные ассеты, больше определенного размера. Пока прорабатываем другие варианты.
        0
        Вот… да. Я пока толкового решения не нашел: как организовать простой контроль версий для Unity — без оверхеда с настройками, процессами и поднятием своего сервера.

        В итоге, в маленьких-быстрых проеках, обмениваемся ассетами через… яндекс диск. Оказалось проще всего. Но, конечно, контроля версий не хватает.

        Для крупного использовали TFS\SVN на своём сервере.

        И то и другое — изрядный компромисс. Хочется простого и красивого решения.
          0
          Largefiles в Mercurial?
      +1
      Вопрос2: Правильно я понимаю, что UCB дает возможность разрабатывать iOS версии ПО без мака?

      ps: Спасибо за интересную, развернутую статью! :)
        +2
        Скорее, UCB дает возможность собирать приложения под iOS без мака. Разрабатывать под iOS без мака позволяет Unity)
        Единственное, для чего может понадобиться мак, это для генерации ключей для сертификатов, для подписки билда.
          +1
          А, да, точно. Билд же подписывать всё-равно. Спасибо, расклад ясен.
          Но в любом случае здорово… отдельный мак только для сборки держать — перебор :)
        0
        Как Asset Server в сравнении с git-ом?
        Пока в голову лезет по-максимуму все держать в коде, включая подключение и навешивание абсолютно всего.
          0
          Я сначала использовал svn для проектов на Unity. Потом в какой-то момент перешел на git, в нем мне понравилось удобство работы с ветками и возможность локально работать с репозиторием, ну и git-flow (хотя сама парадигма не относится именно к git, ее можно применять и в других VCS). Но когда познакомился с Asset Sever, был шокирован отсутствием веток и методом разрешения конфликтов. Фактически, он ничем не отличается от Dropbox-подобных систем, только работает конкретно с самим Unity-проектом. Есть возможность посмотреть версии отдельного ассета, все цепочку коммитов, но на этом полезные свойства заканчиваются. И нужно поднимать свой сервер.
            0
            Вот именно этого я и опасаюсь — dropbox-like системы
              0
              Разрешать конфликты на Asset Sever можно. Для тестовых файлов есть merge. Если конфликт произошел c ассетами, то есть выбор какой ассет использовать свой или чужой (merge тут конечно нет).
                +1
                Вообще сейчас мы начали практиковать такой подход: в настройках редактора включаем текстовую сериализацию ассетов и льем весь проект в Git.
                  0
                  Да, мы так же. Есть еще UniMerge и GitMerge для Unity.
              0
              Спасибо конечно за то, что посветили в то, что есть cloud build. Но не проще ли (как минимум быстрее) сделать локальный гит-сервер. И написать скрипты на каком-нибудь питоне для автоматизации процессов.
              Да и потом есть такая вещь как дженкинс…
                0
                Выбирать вам. 5 минут на настройку в UCB, или день на настройку всего локально. А потом поддержка…
                  0
                  Это да.
                  +1
                  Зависит от ваших требований к CI. У автора была задача «CI за день» и UCB с ней справился.

                  Если компания достаточно крупная и имеет желание и средства настроить свой CI/CD тогда Jenkins, Bamboo, TeamCity и т.д.
                  Мне приходилось раньше работать с Bamboo, сейчас с Jenkins, только специфика — мобильные приложения.

                  Конечно преимуществ в своем собственном CI много, только по моему опыту настроить все это дело а потом и поддерживать — задача непростая. Но с другой стороны это очень интересная область и все больше и больше контор, занятых разработкой мобильных приложений, задумываются о серьезном подходе к CI.
                  0
                  Да, да, конечно согласен.
                  А что из них (Jenkins, Bamboo, TeamCity) Вам больше понравилось?
                    0
                    С Bamboo работал долгое время, больше года. Теперь имею дело с Jenkins. С TeamCity опыта нет.

                    Пока мне нравится Jenkins по одной причине — Jenkins Job DSL плагин. Как для разработчика, для меня это была настоящая находка. Я могу генерировать билд планы (проекты?) автоматически с помощью Groovy скрипта. Причем этот скрипт может быть сколь угодно гибким и я получаю возможность использовать Java код, классы, наследование и все эти ООП прелести, плюс кучу библиотек и т.д. и т.д. В Job DSL добавлена поддержка для большинства популярных плагинов и сообщество активно добавляет новые фичи. Можно также генерировать новые View (вкладки), группировать проекты по папкам и многое другое. Короче, легче было бы перечислить что этот плагин не умеет.

                    Один из минусов — порог вхождения, но по большому счету выучить Groovy на базовом уровне будет достаточно для начала.

                    У Bamboo ничего подобного и близко нет. Насчет TeamCity не знаю.
                      0
                      Хм, спасибо за плагин, интересно выглядит.
                      У нас юнити билдится своим собственным скриптом по образу и подобию примеров типа PerformBuild.cs, далее уже xcode из Shell steps, там все просто и прозрачно…

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое