Continuous Integration с Unity
С переходом на новый проект на Unity с относительно большой командой разработчиков резко встала необходимость автоматической сборки и доставки приложения на устройства для тестирования. Вот как с этим обстояла ситуация, когда я пришел на проект (под iOS): На отдельной mac-машине проект вручную выкачивался из репозитория (Asset Sever). Вручную (File→Build Settings→Build & Run) запускалась сборка в xCode-проект. Далее в xCode делался архив (Archive). Архив экспортировался в ipa-файл, который вручную загружался в TestFlight. Далее, уже в TestFlight доступ предоставлялся нужным тестерам. Все описанное выше автоматизируется с помощью так называемой непрерывной интеграции (англ. Continuous Integration, CI). На моих предыдущих проектах для этих целей использовался TeamCity от JetBrains (создателей удобного инструмента рефакторинга кода Resharper). TeamCity (TC) — очень мощный программный продукт, выполняющий цели, поставленные перед системой непрерывной интеграции, на все 100%. Он умеет даже больше. Но речь в статье пойдет не о нем (о нем уже есть статьи на хабре), а о новом сервисе Unity Cloud Build, специально для разработчиков на движке Unity.Для начала хочу предупредить, что некоторые ссылки ниже требуют доступ к Unity Cloud Build, его форуму и документации. Проект у нас большой, и вся процедура, описанная выше, занимала от получаса и более. Mac, на котором делались сборки, был медленным. Приложение на устройство программисты устанавливали редко (все проверялось, в основном, в редакторе). И поэтому, одного подхода обычно было недостаточно, т.к. после загрузки на устройство в приложении внезапно (по закону подлости) обнаруживались ошибки. К тому же не было нормального QA. В дополнении, все это делалась вечером в пятницу — т.е. получаем все неблагоприятные для такого важного дела условия :)Понятное дело, что так больше продолжаться не могло. Решение должно было быть, естественно, комплексным, и в качестве одной из его частей я поставил задачу: внедрить в разработку CI. Задача ставилась так:
система CI должна быть по возможности бесплатной; должна поддерживать сборку Unity-проектов; её настройка должна быть очень простой; на все про все — не более одного рабочего дня. В прошлый раз в TeamCity я убил как раз где-то день на настройку первой сборки, но потом еще продолжительное время настраивал и поддерживал эти сборки. К тому же он требует размещения на своем сервере, его настройку и поддержку. А в этот раз я решил попробовать Unity Cloud Build. В последнее время я много о нем слышал и в первую очередь меня купило то, что не нужно иметь свой сервер и mac в качестве машины для сборки, все делается на их стороне.Unity приобрела платформу Tsugi и на ее базе построила Unity Cloud Build. Пока она в режиме Beta, бесплатная, доступ есть всем разработчикам с Pro-версией 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.В UCB есть несколько возможностей «поделиться» сборкой: Collaborators. Это список всех, кто имеет доступ к проекту. По окончанию сборки, каждому из этого списка будет приходить сообщение на почту с ссылкой для установки. Можно перейти по ней на устройстве и установить приложение в одно касание. А можно зайти в админку из браузера на компьютере и скачать ipa-файл и дальше уже делать с ним все, что вздумается. У этого метода есть один недостаток — все из этого списка получают доступ к настройкам сборки и всем собранным приложениям. Share via Link. Генерируется ссылка, по которой можно будет скачать конкретную сборку. Push to TestFlight. Как ни странно, это очень удобная опция, когда можно загрузить приложение на TestFlight в три клика. При этом UCB запоминает все настройки доступа и в следующий раз не нужно будет их вводить снова. На форуме UCB предлагалось сделать опцию автоматической загрузки в TestFlight, но в свете последних событий, видимо, такой опции уже не будет. Кому интересно, читайте тут. Кол-во сборок неограниченно. Например, в бесплатном TC есть ограничения на кол-во агентов (так у них называются машины для сборки) и кол-во сборок. На дополнительные нужно покупать доплицензии. Кол-во людей, которых можно подключить к сборке, неограниченно. Т.е. можно хоть всей команде дать доступ к сборке, и на каждый их чих-пых коммит они будут получать себе версию на устройство (одна из основных идей CI). 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 — можно отдельно задать список сцен для сборки. Может пригодиться, например, если для тестов есть особые тестовые сцены. Проект собирается относительно долго. Сейчас проект, который локально собирается за 5–10 мин, на UCB собирается за 15–50 мин. Причина в том, что UCB не позволяют хранить его у себя, и каждый раз он заново загружается из репозитория. Единственная оптимизация, которая есть, это опция Cache Library Directory — позволяет кешировать для проекта папку Library, так что при новой сборке не приходится снова все экспортировать. В целом для разработки это время не столь критично, если у программистов есть возможность собирать проект локально, для своих тестов. К тому же, UCB сейчас предоставляет так называемые «выделенные серверы» (dedicated servers), в которых они обещают очень быструю сборку за счет кеширования всего проекта на их сервере — первый шаг к платным опциям. За подробностями обращаться к разработчикам. Мы собираемся его попробовать. Нет возможности настроить сборку из семейства веток, типа 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, приходилось собирать проект локально, по-старинке) Итак, мне Unity Cloud Build пришелся по душе. Проект развивается, на форуме спрашивают о текущих запросах разработчиков и постепенно их реализуют. Если вы разрабатываете проекты на Unity и задумались о CI, рекомендую попробовать Unity Cloud Build. Сэкономите время и деньги.Плюсы:
Быстрая настройка. При готовых сертификатах, профилях и ссылке на репозиторий займет всего 2 минуты. За Pro-лицензию получаем возможность «бесплатно» собирать под Android и iOS, их лицензии не требуют, и даже mac не потребуется. Дополнительные возможности по настройке сборки. Кол-во сборок, проектов, персон с доступом к проекту неограниченно. Минусы: Относительно долгое время сборки. Нет поддержки Hg, TFS, Asset Server (хотя последними двумя я не рекомендовал бы пользоваться). Нет встроенной поддержки автоматических тестов. Жду вопросы, предложения, уточнения в комментариях!
Возможно, кому-то будет интересно почитать мои предыдущие статьи:
Удачи вам в разработке!