top of page

Тысяча запусков сборки в месяц, и ни один не стоит ни копейки ⚙️

Фото автора: Marcel Dütscher
Marcel Dütscher
26 июл.
3 мин. чтения

Сначала поправка. В первой версии этой статьи утверждалось, что у нас закончились минуты сборки на GitHub и из-за этого пришлось перейти на аккаунт Pro. Это было неверно, и достаточно было одного взгляда в документацию: для публичных репозиториев минуты сборки на GitHub бесплатны. Артефакты и кеши тоже. Наш репозиторий публичный с конца мая, так что мы ни разу не заплатили за минуту и не заплатим. Вместо того чтобы тихо поправить текст, мы решили переписать его и рассказать, что на самом деле показали измерения. Оказывается, это гораздо интереснее неправильной версии.


Сначала гадали, потом смотрели. Поводом стал вечер, когда готовый pull request висел в браузере и ни одна проверка не запускалась. Ни зелёных галочек, только тишина. Мы сразу выбрали очевидное объяснение, «квота исчерпана», и купили Pro. После этого всё снова заработало, что вроде бы подтверждало теорию. Но нет: у тишины была другая причина (pull request, который GitHub в этот момент не может чисто слить с основной веткой, не запускает никаких проверок). С тех пор мы запросили данные биллинга по каждому отдельному запуску. Ответ для каждого запуска и каждой операционной системы: оплачиваемое время = 0 миллисекунд. Поддержать платформу подпиской — совершенно нормально, но как объяснение для этого репозитория это не работает.


Что правда: механизм разросся. Каждый pull request запускает небольшую фабрику: собирается весь сервер и гоняется его набор тестов, линтер и анализ кода просматривают изменения, CodeQL ищет дыры в безопасности, а ещё создаются Docker-образы для игрового сервера, портала, WorldHost и ИИ-бэкенда. Релиз добавляет сборки клиента под Windows, Linux и macOS, а также версию WebGL для браузерной игры. С конца мая набралось 1 723 запуска сборки, 1 092 из них только в июле, и это за четыре недели при 131 влитом pull request. И да, недавний всплеск действительно связан с ИИ 😉: проект разрабатывается на 100% с помощью ИИ, а с подпиской побольше просто происходит больше всего параллельно. Только валюта здесь не деньги, а время ожидания.


Куда уходит время ожидания. Замер за восемь дней: обычный прогон проверок (CI) — 379 минут, анализ безопасности CodeQL — 230, сборки релизов — 126, остальное мелочь. Один релиз стоит около 110 минут вычислений, распределённых между WebGL (31,6), Docker-образом (19,4), macOS (13,7), Linux (13,7), большим тестовым заслоном (12,1), Windows (10,9) и упаковкой (7,2). Это время между «готово» и «можно установить».


А теперь то, чего действительно не хватает: кеш. Чтобы сборка каждый раз не начиналась с нуля, GitHub хранит промежуточные результаты, и на это даётся 10 ГБ на репозиторий, как бы публичен он ни был. У нас сейчас там 5,3 ГБ в 63 записях. Проблема в распределении: примерно две трети составляют промежуточные слои Docker, которые загружаются заново при каждом запуске и вытесняют как раз то, что помогло бы больше всего. Это настоящее узкое место, и никакая подписка в мире не позволит его обойти.


Самой приятной находкой стал настоящий баг. При сборке Unity создаёт огромную промежуточную папку (Library), повторное использование которой экономит минуты. Измерения показали: для Windows, Linux и macOS эта папка никогда не сохранялась: сборки добросовестно пытались её восстановить, но никто её никогда не записывал. А сборка для Windows была единственной с ключом кеша без пометки платформы. Итог: она скачивала 1,7 ГБ промежуточного состояния для WebGL, которое Unity потом добросовестно выбрасывало, прежде чем заново импортировать всё. Журнал показывает это чёрным по белому: 257 секунд импорта ресурсов вместо 85 при тёплом кеше. Это почти девять минут впустую на каждый релиз — потому что в ключе не хватало одного слова.


Что ещё всплыло. Наш набор тестов запускается три раза на каждый отправленный коммит (в pull request, после слияния и ещё раз при релизе). CodeQL проверяет три языка в каждом pull request, хотя это даже не обязательная проверка. Кеша для пакетов .NET нет вообще. Эмулятор для чужих архитектур процессоров настраивается, хотя мы собираем только под одну. А 7,4 ГБ старых артефактов сборки лежат с хранением по умолчанию в 90 дней. Ничего драматичного, но вместе это приличный кусок жизни.


Урок тот же, что нам преподал наш сервер. Тогда мы измерили, что половина занятой памяти уходит вовсе не на игру, а на Docker и мониторинг. На этот раз ещё неловче: мы предположили счёт, которого никогда не было, и заплатили, не проверив. Измеряй, а не гадай — похоже, эта фраза действует, пока по-настоящему её не усвоишь. Работа по наведению порядка запланирована, но ещё не сделана; когда она пройдёт, мы расскажем, что она нам дала. 🚀

Недавние посты

Смотреть все

Комментарии


Комментарии к этому посту больше не доступны. Обратитесь к владельцу сайта за дополнительной информацией.
bottom of page