25 нояб. 2024 г.·6 мин чтения

Правила хранения артефактов, которые сокращают расходы на хранение CI

Правила хранения артефактов помогают сократить пустую трату места в CI. Узнайте, что хранить, когда истекать сборки и как аккуратно сохранять доказательства релизов.

Правила хранения артефактов, которые сокращают расходы на хранение CI

Что идёт не так, если хранить каждую сборку

Большинство команд попадает в это случайно. CI-система идёт с щедрыми настройками по умолчанию, никто их не меняет, и артефакты каждой сборки хранятся намного дольше, чем нужно.

Объём хранилища растёт быстрее, чем думают люди, потому что выход сборки умножается на каждом шаге. Ветка фичи создаёт артефакты. Pull request создаёт другой набор. Повторный запуск из‑за нестабильного теста добавляет ещё. Небольшая правка часто создаёт почти идентичную копию. В маленькой команде это быстро суммируется.

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

Доказательства релиза — другое дело. Вам может потребоваться точный пакет релиза, контрольная сумма, подписанный лог или короткая запись о том, какой коммит был выкатлен. Эти файлы важны при откате, проблемах у клиента или при аудите. Хранение каждой упавшей сборки, каждого повтора и каждого промежуточного файла не равнозначно хранению полезных доказательств.

Загромождение также тратит время. Когда баг появляется в продакшне, люди просматривают длинные списки похожих артефактов и угадывают, какой соответствует релизу. При аудите тот же беспорядок превращает простые вопросы в долгую работу. Команды скачивают неверный архив, сравнивают неправильный отчёт и теряют время, которого нет в счёте за хранение.

Чёткие правила хранения артефактов снижают затраты на CI и делают архив более надёжным. Когда шумные файлы истекают по расписанию, важные файлы остаются в легкодоступном виде.

Решите, что заслуживает хранения

Большинство пайплайнов создаёт гораздо больше файлов, чем кто‑то когда‑либо снова откроет. Один прогон может оставить сырые логи задач, тестовые отчёты, файлы покрытия, скриншоты, бинарники, инсталляторы, кэши, временные папки, контрольные суммы, SBOM, подписи и заметки релиза. Если вы не сортируете эти файлы целенаправленно, каждый прогон оставляет небольшой ворох возможно полезных выходных данных, и хранилище продолжает расти.

Практичная политика начинается с трёх корзин хранения.

Три корзины хранения

Первая корзина — доказательства релиза. Это небольшой набор, который может понадобиться через месяцы: точный пакет релиза, контрольная сумма, подпись, метаданные версии, манифест зависимостей и любые отчёты, подтверждающие, что именно было выпущено. Если саппорт должен воспроизвести проблему клиента или клиент просит инсталлятор старой версии, этот набор экономит время.

Вторая корзина — краткосрочный вывод для отладки. Логи тестов, скриншоты, дампы крашей и отчёты покрытия помогают сразу после упавшего прогона. Через две недели большинство из них уже не актуальны. Храните их достаточно долго, чтобы инженеры успели расследовать, затем дайте им истечь.

Третья корзина — одноразовый вывод. Временные рабочие пространства, промежуточные бандлы, дублирующие архивы и распакованные файлы зависимостей обычно туда и относятся. Если повторный запуск восстанавливает их за несколько минут, хранить их месяцами — бессмысленно.

Причина для хранения файла должна помещаться в одно предложение. «Клиенту может понадобиться этот инсталлятор позже» — это реальная причина. «Возможно, нам это когда‑нибудь снова пригодится» — не причина.

Исключения должны исходить от саппорта, комплаенса или доставки клиенту, а не от привычки. Подписанные пакеты релизов, отчёты для аудита, скрипты миграции и манифесты деплоя часто требуют более длительного хранения, потому что кто‑то за пределами команды сборки может на них полагаться. Прошедший тестовый лог из старой ветки обычно не нуждается в этом.

Если небольшая команда использует GitLab или другую CI‑систему, такое разделение уже убирает много мусора. Храните доказательства того, что дошло до пользователей. Храните данные отладки кратко. Удаляйте остальное.

Задайте понятные сроки истечения по типу артефакта

Хранилище дорожает, когда все артефакты получают одинаковое обращение. Пакет релиза, который ещё используется клиентами, выполняет совсем другую задачу, чем сборка pull request'а, которую никто не собирается выкатывать.

Начните с одного вопроса: кто будет нуждаться в этом позже и как долго? Если ответ расплывчат, срок должен быть коротким.

Полезное исходное расписание на практике выглядит так. Храните выпущенные пакеты в течение полного окна поддержки плюс небольшой буфер. Храните рутинные тестовые отчёты 14–30 дней. Истекайте сборки pull request'ов и веток через 3–7 дней, если они не были выпущены. Если Sentry или ваша система наблюдаемости уже владеют логами, не дублируйте эти данные в CI месяцами. Сохраняйте один снимок исходников на релиз вместо каждого прогона ветки.

Доказательства релиза заслуживают особой заботы. Аудиторы, команды поддержки и будущие инженеры могут понадобиться доказать, что вы выпустили. Храните пакет релиза, точный коммит или тэг, манифест зависимостей и короткую запись сборки. Обычно вам не нужен полный временный workspace, каждая промежуточная прослойка или все логи отладки.

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

Сборки pull request'ов — хорошее место для строгих правил. Они быстро накапливаются, особенно когда люди перезапускают задания ради мелких правок. Если ветка устарела или смержена, счётчик должен уже идти.

Одно правило упрощает очистку: если два системы хранят одни и те же доказательства, выберите одного владельца. CI хорошо показывает, как был собран релиз. Обычно это не лучшее место для долгосрочного хранения логов, скриншотов, кэшей и снимков веток.

Когда даты различаются по типам артефактов, затраты на хранилище CI перестают расти незаметно.

Постройте политику в несколько шагов

Начните с полного инвентаря. Большинство команд знают, что хранят вывод сборок, но забывают про тестовые отчёты, слои контейнеров, архивы кэша, экспорт сканеров безопасности и единичные файлы, добавленные старыми заданиями. Проверьте каждый репозиторий и каждый пайплайн, включая задания, которые никто не трогал месяцами. Старые привычки CI часто стоят дороже, чем активная работа.

Затем измерьте, что вы уже храните. Разбейте место по проектам, веткам, типам артефактов и возрасту. Такой обзор обычно быстро выявляет реальную проблему. Небольшая команда может обнаружить, что feature‑ветки создают большую часть объёма, в то время как релизные сборки занимают меньше места и намного важнее.

После этого задайте понятные по умолчанию значения. Артефакты pull request'ов и feature‑веток должны храниться только достаточно долго, чтобы отладить падения. Артефакты main должны оставаться достаточно долго для недавних откатов. Пакеты релизов должны храниться дольше с чёткой ответственностью. Логи и отчёты остаются только если их кто‑то реально читает после первых нескольких дней.

Запишите эти значения простым языком. «Временные тестовые артефакты истекают через 7 дней» гораздо лучше, чем расплывчатое формулирование про «периодический обзор файлов». Команды соблюдают правила, которые легко запомнить.

Затем добавьте небольшой слой исключений. Некоторым файлам требуется более длительное хранение, потому что они поддерживают релизы, аудиты, юридические записи или доставку клиенту. Храните их целенаправленно. Не дозволяйте «может пригодиться» стать общим оправданием для сохранения всего подряд. Если клиенту нужен подписанный пакет, сохраните этот пакет и сопутствующие доказательства, а не полное рабочее пространство каждого прогона.

Пересматривайте политику по расписанию, например ежеквартально, и снова после серьёзных изменений рабочего процесса. Новый процесс релизов, переход на контейнеры или большая тестовая база быстро меняют паттерны использования хранилища. Если вы никогда не вернётесь к правилам, старые настройки останутся, и расходы снова поползут вверх.

Лучшие политики — скучные. Люди знают, что хранится, что истекает и кто может утверждать исключение. Это уменьшает потери без усложнения использования CI.

Храните доказательства релиза, а не полные рабочие пространства

Упростить архив CI
Храните только действительно нужные файлы и перестаньте сохранять одно и то же доказательство дважды.

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

Для каждой выпущенной версии держите компактную запись, которая ясно рассказывает историю. Сохраняйте пакет релиза, точный хеш коммита, номер версии, дату сборки, контрольную сумму, ID пайплайна, запись об утверждении и короткие сводки тестов и сканов безопасности. Этого достаточно, чтобы ответить на вопросы: что вышло, когда вышло и какой код это породил.

Маленький манифест обычно лучше полного рабочего пространства. Его проще искать, копировать и проверять. Рабочее пространство — противоположность: там часто есть скачанные зависимости, временные файлы, отладочные данные и другой мусор, который никто больше не проверяет.

Это особенно важно для небольших команд. Если через полгода возникнет проблема с релизом, вы хотите чистую запись, которую любой может прочитать за пару минут, а не многогиговый архив, требующий специнструментов, чтобы найти номер сборки.

Определите владельцев заранее. Решите, кто может продлевать сроки хранения релиза, кто может удалять запись релиза и когда нужно согласование. Во многих командах это инженерный лидер или владелец комплаенса. Чёткие правила хранения артефактов останавливают случайные исключения от превращения в постоянный рост хранилища.

Храните доказательства того, что вы выпустили. Удаляйте остальное целенаправленно.

Реалистичная настройка для небольшой команды

Представьте небольшую SaaS‑команду с одним главным репозиторием и привычкой выкатывать релизы ежедневно. Они открывают pull request'ы весь день, несколько раз мержат в main и тегируют релиз, когда изменение готово для клиентов. Если хранить все артефакты навсегда, хранилище будет тихо расти каждый месяц.

Практичная политика для такой команды может быть простой. Сборки pull request'ов истекают через 3–7 дней. Файлы отладки из main остаются около 14 дней. Тегированные пакеты релизов хранятся всё окно поддержки, а записи релизов — на тот же срок.

Это первое правило убирает самый большой объём. Review‑сборки быстро накапливаются, особенно когда люди пушат несколько раз в тот же pull request. Неделя обычно достаточно для код‑ревью, проверок QA и ещё одного быстрого взгляда, если что‑то ломается сразу после слияния.

Файлы отладки main требуют немного больше времени. Две недели дают команде пространство, чтобы проверить проблему в продакшне, сравнить логи или воспроизвести баг по недавнему изменению. После этого команда обычно понимает, важна ли ещё сборка.

Тегированные релизы — другое дело. Если клиенты могут использовать версию шесть месяцев, год или дольше, команда должна хранить пакет релиза в течение этого окна поддержки. Также нужно хранить запись релиза, а не только бинарник. Эта запись может содержать имя тэга, SHA коммита, дату сборки, контрольную сумму пакета, сводку тестов и снимок зависимостей.

Через месяцы саппорту не нужны все временные рабочие пространства от каждой упавшей ветки. Им нужны доказательства того, что было выпущено. Если клиент сообщает баг в версии 2.8.4, саппорт должен иметь возможность достать тэгнутый пакет, сверить контрольную сумму, подтвердить точный коммит и просмотреть тестовую сводку этого релиза. Это быстро. Копаться в тысячах старых review‑сборок — нет.

Ошибки, которые тихо увеличивают счёт за хранилище

Проверьте правила хранения CI
Практический обзор того, что хранить, что удалять и где прячутся утечки места.

Команды редко доводят расходы на CI до рекорда одним драматичным шагом. Счёт обычно растёт из‑за мелких привычек, кажущихся безобидными.

Одна типичная ловушка — хранить почти всё, потому что хранилище сначала кажется дешёвым. Сначала команда может запускать десять сборок в день и считать, что ничего удалять не нужно. Потом растут тестовые выводы, накапливаются скриншоты, и каждый merge request оставляет копию тех же файлов.

Другая ловушка — одно правило истечения для всех артефактов. Пакеты релизов, временные тестовые отчёты, логи отладки и кэши зависимостей выполняют разные задачи. Если вы даёте всем 90 дней, вы храните слишком много мусора и при этом рискуете удалить единственный нужный файл.

Дублирование хранения — ещё одна тихая утечка. Многие команды сохраняют логи внутри артефактов CI и одновременно отправляют те же логи в центральную систему логирования. Это значит, что вы платите дважды за одно и то же доказательство. Оставьте версию, которой реально пользуются, и удалите другую.

Часть роста прячется в местах, которые никто не проверяет часто: упавшие задания с полным выводом отладки, повторные пайплайны, сохраняющие ещё один полный набор артефактов, форки, которые запускают похожие задачи, временные ветки, которые никогда не чистят, и старые пайплайны merge request'ов, оставшиеся после удаления ветки.

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

Небольшая команда может избежать большей части этого одной привычкой: пересматривать настройки хранения ежемесячно. Проверяйте, что выросло, спрашивайте, зачем это ещё существует, и удаляйте всё, что никто не открывал, не скачивал и не использовал в реальном обзоре релиза. Счета за хранение остаются ниже, когда удаление становится частью обычной работы по CI/CD, а не экстренной чисткой.

Быстрая проверка до и после очистки

Исправить шумное хранилище GitLab
Уберите шум в сборках веток, повторах, кэшах и старых выводах задач без догадок.

Очистка должна оставить меньше файлов и меньше споров. Перед удалением чего‑либо задайте один простой вопрос про каждый артефакт: зачем он существует? Если никто не может ответить одним предложением, вероятно, его не стоит хранить долго.

Звучит просто, но быстро выявляет расточительность. Команды часто держат старые тестовые бандлы, дублирующие отчёты и выводы упавших сборок, потому что никто не трогал настройки по умолчанию. Хорошие правила хранения артефактов начинаются с владения, а не с расчёта места.

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

Один тест помогает больше большинства дашбордов. Возьмите последний продакшн‑релиз и попросите того, кто его не собирал, собрать доказательства релиза: ID сборки, коммит, краткое резюме тестов, контрольные суммы пакета и запись деплоя. Если человек застрянет, проблема не только в хранении — путь извлечения сломан.

После очистки наблюдайте за поведением, а не только за общим количеством гигабайт. Одноразовый спад радует, но настоящая победа — это более медленный рост без дополнительных проблем для саппорта или инженеров.

В течение следующих недель недельный прирост хранилища должен выровняться. Саппорт всё ещё должен спокойно находить последний пакет релиза и доказательства того, что было выпущено, без просьб инженерам копаться в старых заданиях. Артефакты упавших сборок должны исчезать по расписанию, а доказательства релиза — оставаться доступными. Дублирующие отчёты должны перестать появляться в нескольких местах.

Если рост не замедляется после очистки, проблема не только в политике. Пайплайн всё ещё продуцирует файлы, которые никто не проверяет. Исправьте это в первую очередь, тогда очистка будет работать устойчиво.

Что делать дальше

Выберите один загруженный репозиторий и сначала измените только его настройки хранения. Две недели обычно достаточно, чтобы понять, вызывают ли более короткие сроки реальные проблемы или никто не скучает по старым файлам. Этот маленький эксперимент даёт больше, чем догадки, и даёт чистую картину изменений в расходе на хранение CI.

Перед удалением старых артефактов запишите минимальный набор доказательств релиза, который команда должна сохранять. Во многих командах это просто: тэг версии, SHA коммита, финальный пакет или ID образа, контрольная сумма, результат тестов, примечание об утверждении и короткое резюме сборки. Храните доказательства того, что вы выпустили. Обычно вам не нужны все временные файлы каждого прогона.

Безопасный разворот прост. Выберите один репозиторий с частыми сборками, сократите сроки для временных артефактов, логов и кэшей, храните доказательства выпущенных релизов в отдельном месте с более длинным сроком, и просмотрите использование хранилища, ошибки пересборки и трение релизов через две недели. Не меняйте все репозитории сразу. Один пилот проще откатить и покажет, откуда команда реально зависит на старых артефактах.

Во время пилота следите за двумя проблемами. Пересборки могут падать, если что‑то истекло слишком рано, и проверки релизов могут ломаться, если никто не определил минимальный набор записи. Обе проблемы полезны: они точно укажут, где политику нужно поправить.

Включите обзор хранилища в график обзора релизов. Если ждать счёта‑сюрприза, вы пропустите медленный рост, вызванный одной лишней копией архива в каждом пайплайне, скопированной и хранимой месяцами.

Если у команды нет постоянного владельца CI, Oleg Sotnikov at oleg.is может просмотреть правила хранения артефактов, расходы на инфраструктуру и настроить экономичные сборки в рамках Fractional CTO или консультационной работы.

Запустите пилот, измерьте результат и примените ту же политику ко всем остальным репозиториям.

Часто задаваемые вопросы

What should we keep for each release?

Сохраняйте небольшой реестр релиза: финальный пакет или образ, коммит или тэг, контрольную сумму, дату билда, ID пайплайна и краткое резюме тестов. Этого достаточно для поддержки и разработки, без лишнего груза.

How long should pull request artifacts live?

Начните со сроков 3–7 дней для артефактов pull request'ов и feature-веток. Обычно этого достаточно для ревью, QA и быстрой проверки после слияния.

Do we need to keep old test reports?

Да, но обычно недолго. Обычные тестовые отчёты храните примерно 14–30 дней, затем удаляйте их, если нет активного инцидента или требований соответствия.

Should we keep logs in CI if another tool already stores them?

Нет, не для долгосрочного хранения. Если Sentry, Grafana или другой инструмент уже хранит логи, пусть он будет источником истины — не храните те же данные в CI месяцами.

What is the fastest way to cut CI storage costs?

Ужесточите сроки хранения для сборок веток, повторных запусков и файлов отладки в первую очередь. Эти файлы накапливаются очень быстро, и большинство команд не открывают их снова через несколько дней.

How do we decide if an artifact deserves long retention?

Задайте простой вопрос: кто будет это использовать позже и как долго? Если никто не может ответить коротко — срок хранения должен быть коротким или файл можно удалить.

Should we keep full workspaces for shipped builds?

Как правило, нет. Храните доказательства релиза, а не полные рабочие пространства с зависимостями, временными файлами и дублирующими выходами, которые можно пересобрать при необходимости.

How often should we review artifact retention rules?

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

What can go wrong if we delete artifacts too aggressively?

Риск — это сбои пересборки, потерянные доказательства релиза или задержки в поддержке. Поэтому сначала проведите небольшой пилот, чтобы понять, какие артефакты действительно нужны.

How do we test a new retention policy safely?

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