В небольшой студии мобильных игр из Алматы сборка релиза занимала вечер и одного конкретного человека. Наводил порядок в этом процессе Евгений Росляков. Пишу код и настраиваю инфраструктуру разработки с 2016 года; работаю как самозанятый, с договором и закрывающими документами; живу в Москве, работаю удалённо с командами в разных странах.
Студия делает казуальные головоломки для Android и iOS. В команде шесть человек: три программиста, два художника и геймдизайнер, который заодно ведёт сайты игр. Игры собираются на игровом движке, художники работают в тяжёлых графических файлах.
Весь проект лежал в Subversion. Так повелось с первого прототипа, и для своего времени это было нормальным решением. Но с ростом команды начались знакомые проблемы: ветки никто не делал, потому что сливать их в Subversion было больно; программисты коммитили в общий ствол и ломали друг другу сборку; откатить неудачную правку в середине недели означало полдня разбирательств.
Релизную сборку делал ведущий программист на своём ноутбуке. Только у него были настроены ключи подписи, нужные версии инструментов и сертификаты для магазинов. Когда он уходил в отпуск, релизы ждали.
Сайты игр — короткие страницы с трейлером и ссылками на магазины — геймдизайнер правил прямо на хостинге, и каждый раз что-то ехало.
Сначала договорились о правилах, потом настраивали инструменты. Записал простой процесс: у каждой задачи своя ветка, в общий ствол код попадает только через запрос на слияние, который кто-то посмотрел и который прошёл автоматическую сборку. Никаких «закоммичу сразу, потом поправлю».
Код перенёс из Subversion в GitHub вместе с историей. Сопоставил авторов старых коммитов с новыми учётками, проверил, что метки релизов превратились в теги, а не потерялись. Большие бинарные файлы движка вынес в хранилище больших файлов, чтобы репозиторий не весил гигабайты.
Художественные исходники оставили в Subversion. Это решение я отстаивал сознательно: у художников огромные многослойные файлы, которые нельзя сливать, и блокировка файла в Subversion для них удобнее, чем любые обходные пути в Git. Программистам из этого хранилища нужны только экспортированные картинки, и они попадают в GitHub автоматически.
Сборки настроил в Jenkins на собственных машинах студии. Облачные сборщики для iOS обходятся дорого, а в офисе уже стоял компьютер с macOS, которого достаточно. Ключи подписи и сертификаты теперь лежат в хранилище секретов Jenkins, а не на чьём-то ноутбуке. Каждое слияние запускает сборку под обе платформы и тесты; ночью собирается полная тестовая версия и уходит тестировщикам.
Релиз стал отдельной кнопкой. Ведущий или любой другой программист с правами нажимает её, Jenkins собирает подписанные версии, проставляет номер и отправляет их в консоли магазинов на проверку. Весь цикл CI/CD описан в файле в репозитории, так что его можно читать и менять как обычный код.
Сайты игр перенёс на Vercel. Геймдизайнер правит страницу в отдельной ветке на GitHub и сразу получает ссылку на превью, которую можно показать издателю до публикации. После слияния сайт обновляется сам, а предыдущая версия доступна для отката одной кнопкой.
Релиз больше не зависит от одного человека. Последнюю версию игры выпускал программист, который пришёл в студию за месяц до этого, по инструкции из пяти шагов.
Общий ствол почти перестал ломаться. Если что-то и проскакивает, Jenkins сообщает об этом в рабочий чат через несколько минут, с именем ветки и ошибкой, и разбирается тот, кто это сделал.
Художники работают так же, как раньше, и почти не заметили переезда. Это было одной из целей: не ломать работу людям, которым Git ничего не даёт.
Сайты игр теперь обновляются без нервов. Издатель видит превью до публикации, а правки на «живом» хостинге остались в прошлом.
Слабое место осталось одно: сборщик iOS всего один, и в дни больших обновлений к нему выстраивается очередь. Вторую машину студия купит, когда начнёт выпускать игры чаще.
Если ваша команда собирает релизы вручную и боится каждого слияния, напишите мне через freelance.ru. Опишите, как устроена разработка сейчас, и я предложу план без резкой ломки привычек.