Один отдельный шаг cleanWs уже позволяет Jenkins удалять рабочее пространство по правилу, но это не делает безопасным удаление всех данных на Mac Agent: описание Workspace Cleanup Plugin не заменяет проверку активных задач, архивов и подписей. Если узел получил статус offline из-за диска, сначала исключите его из новых сборок и разложите данные по классам: Workspace, пользовательская Library, временные каталоги, кэши, Runtime и архивы. Только после этого выбирайте очистку; если свободное место быстро снова уменьшается, снижайте параллелизм, отделяйте signing-узел и добавляйте фиксированный или удалённый Mac для CI.
Эта статья для вас, если вы отвечаете за Jenkins Mac Agent, дисковые предупреждения и восстановление узла. Она также пригодится командам, которые управляют Xcode-кэшем, скоростью iOS CI/CD и очередью сборок. Техническим руководителям материал поможет решить, достаточно ли изменить политику хранения или уже требуется дополнительная ёмкость.
Сначала определите источник роста, а не удаляйте Workspace
Типичная аварийная цепочка выглядит так: мониторинг фиксирует малый запас места, Agent переводится в offline, инженер удаляет папку проекта, но доступный объём почти не меняется. Причина в том, что рабочая директория была только одним из потребителей. Крупные данные могли остаться в пользовательской Library, временном каталоге, папке архивов или в другой директории, созданной параллельной сборкой.
Jenkins умеет контролировать свободное место Remote FS и временного каталога узла. Это следует из официальной документации Jenkins по управлению узлами. Но мониторинг показывает проблему, а не владельца данных. Поэтому перед удалением составьте четыре независимых среза:
- фактический путь Remote FS;
- пользовательские каталоги, где Xcode и менеджеры зависимостей хранят рабочие данные;
- временные каталоги и файлы, удерживаемые процессами;
- архивы, логи и опубликованные артефакты.
Для первичного обзора используйте только чтение:
df -h
du -xhd 1 "$JENKINS_HOME_OR_REMOTE_FS" 2>/dev/null | sort -h
du -xhd 1 "$HOME/Library" 2>/dev/null | sort -h
Переменная здесь должна указывать на фактический путь из конфигурации узла, а не на предполагаемую стандартную папку. Для каждого крупного каталога зафиксируйте размер, дату последнего доступа, владельца, активный процесс и возможность восстановления. Не делайте вывод по категории Finder: APFS, логический размер файлов и пространство, которое реально вернётся после удаления, могут различаться.
В Jenkins Pipeline рабочая область назначается автоматически, а при параллельном выполнении могут появляться каталоги с суффиксами. Это описано в документации Pipeline по Workspace. Поэтому удаление основной папки проекта не гарантирует, что параллельные или старые рабочие директории исчезли.
Разделите данные по риску и владельцу
Не применяйте одну политику «удалять всё после сборки». У разных объектов различаются владелец, цена восстановления, область повторного использования и допустимый момент очистки.
| Класс данных | Что проверить | Типичное решение |
|---|---|---|
| Jenkins Workspace | Активна ли задача, есть ли параллельные каталоги, можно ли заново получить исходники | Удалять после завершения и публикации результата |
| DerivedData | Нужна ли повторная компиляция, какие проекты используют кэш | Ограничивать срок хранения или чистить в окно обслуживания |
| Simulator Runtime и платформы | Нужны ли SDK тестовой матрице, доступен ли источник повторной установки | Не удалять без проверки восстановления |
| Archives и dSYM | Связан ли архив с опубликованной версией или расследованием | Хранить по политике релизов и диагностики |
| Кэши зависимостей | Используются ли они несколькими задачами, есть ли копия во внешнем хранилище | Сохранять выборочно, а не бессрочно и не удалять каждый раз |
| Keychain и signing-данные | Используются ли они активным процессом публикации | Не включать в общий скрипт очистки |
У такой классификации есть два преимущества. Во-первых, вы видите, кто отвечает за срок хранения: команда CI, релизная команда, владелец проекта или служба безопасности. Во-вторых, решение перестаёт зависеть от размера одной папки. Даже большой кэш может быть дешевле пересоздать, чем повторно загружать через ограниченный канал. И наоборот, небольшой архив может иметь доказательную ценность для выпуска или расследования сбоя.
Что делать с оставшимися Workspace
Проверьте три места:
- фактический Workspace, указанный заданием;
- каталоги, созданные для параллельных запусков;
- директории старых веток и удалённых Job.
Для multibranch Pipeline отдельно проверьте правила хранения старых запусков и веток. Jenkins описывает настройки удаления старых элементов в документации по multibranch-декларациям. Удаление старого запуска не всегда означает немедленное освобождение всех данных на Agent, особенно если проект копирует артефакты в другое место.
cleanWs подходит, когда Workspace можно полностью восстановить из репозитория и внешнего хранилища. В Pipeline его обычно размещают в контролируемом блоке завершения, но перед включением проверьте повторные попытки и параллельные стадии. Для первого теста выберите непроизводственную ветку, сохраните журнал и сравните поведение повторного запуска.
Нельзя удалять активный каталог командой уровня операционной системы только потому, что его имя выглядит устаревшим. Такая операция может оборвать checkout, тест, упаковку или публикацию. Если состояние задачи неясно, сначала временно исключите узел из очереди, дождитесь завершения или отмены процессов и только затем проводите удаление в согласованное окно.
Отдельно обработайте Xcode, симуляторы и релизные материалы
Xcode генерирует несколько типов данных, и их нельзя объединять в одну категорию «кэш». DerivedData чаще всего можно восстановить повторной сборкой, но после очистки увеличивается время первого запуска и возрастает нагрузка на сеть и компилятор. Это не означает, что его допустимо удалять во время активной задачи.
Simulator Runtime и платформенные компоненты имеют другой профиль риска. Их восстановление зависит от конкретной версии Xcode, доступного источника и сетевых ограничений. Порядок загрузки и установки дополнительных компонентов описан в официальной документации Xcode. Перед очисткой составьте список реально используемых SDK и тестовых устройств. Если узел работает в изолированной сети, сначала докажите, что нужный компонент можно вернуть без ручного вмешательства.
Archives и dSYM нельзя считать обычным временным результатом. dSYM нужен для символикации и анализа сбоев; назначение отладочной информации описано в документации Xcode о debugging information. Архив, связанный с выпущенной версией, должен иметь владельца и срок хранения. Релизная команда должна подтвердить, что необходимые материалы уже переданы в утверждённое хранилище.
Важно: отсутствие ошибки в следующей локальной сборке не доказывает, что релизная цепочка сохранена. Для приёмки нужна подписанная публикация или эквивалентный производственный сценарий с проверкой артефакта и dSYM.
Сопоставьте кэши зависимостей и дубли
Проверьте, не существует ли одна и та же зависимость одновременно в Workspace, пользовательском каталоге и внешнем хранилище артефактов. Это относится к Swift Package Manager, CocoaPods, Homebrew, Git LFS и проектным кэшам. Важно не название инструмента, а граница ответственности:
- кто владеет данными;
- можно ли полностью восстановить их;
- сколько задач получают пользу от одной копии;
- что запускает очистку;
- где хранится контрольная или резервная копия.
Отдельно сравните Jenkins Controller, Mac Agent и хранилище артефактов. Если Agent очищается, но Controller или внешнее хранилище получают дубли каждой сборки, общая проблема ёмкости просто перемещается. Если же кэш нужен только одному проекту, постоянное хранение на общем узле может быть неоправданным.
| Объект | Владелец решения | Данные для проверки | Когда менять стратегию |
|---|---|---|---|
| Workspace | Команда CI | Частота повторной загрузки и активные задачи | При росте старых веток или параллельных директорий |
| Кэш зависимостей | Платформенная команда и проекты | Время восстановления, доля повторного использования | Когда кэш растёт быстрее, чем экономит время |
| Архивы и dSYM | Релизная команда | Связь с выпуском, срок расследований | При отсутствии подтверждённого внешнего хранения |
| Simulator Runtime | Владелец тестовой матрицы | Нужные SDK и способ повторной установки | При смене Xcode или сокращении тестовой матрицы |
| Логи и артефакты | CI и служба качества | Требования аудита и срок хранения | При дублировании на нескольких уровнях |
Такой список полезнее фиксированного правила «оставлять кэш на семь дней»: конкретный срок должен следовать из журналов, восстановления и требований релиза. Если у вас нет измерений, сначала включите учёт роста, а не вводите случайный порог.
Вторая проверка: решите, очистка это или нехватка ёмкости
После первой очистки соберите факты за несколько циклов:
- размер каждого класса данных до и после сборок;
- ежедневный прирост;
- пиковое потребление одной задачи;
- число параллельных задач;
- частоту ручной очистки;
- длительность восстановления кэша и компонентов;
- время в очереди;
- число переводов Agent в offline.
Jenkins предоставляет средства управления и наблюдения за узлами, а общие административные настройки описаны в руководстве Jenkins по управлению. Используйте эти данные вместе с журналами, а не только с текущим значением df.
Решение можно принять по следующим условиям:
- Если основную долю занимают старые Workspace, активных процессов нет, а исходники и артефакты восстанавливаются, то применяйте управляемую очистку жизненного цикла.
- Если растёт DerivedData, но повторная сборка приемлема и не нарушает окно публикации, то задайте ограниченное хранение и контролируемое удаление.
- Если пространство занимают Runtime или платформы, необходимые текущей матрице, то не удаляйте их до проверки повторной установки.
- Если архивы, dSYM или подписи не имеют подтверждённой копии, то остановите очистку и передайте решение владельцу релизных данных.
- Если пик одной сборки вместе с параллельными задачами регулярно приближает узел к запрету на приём, то сначала уменьшите параллелизм, затем оцените дополнительный Agent.
- Если очистка требуется чаще, чем команда может безопасно проводить её в окне обслуживания, то проблема уже относится к планированию ёмкости, а не только к гигиене диска.
- Если производственная подпись конфликтует с обычными сборками, то выделите отдельный signing-узел и не рассматривайте общий Mac Agent как универсальный ресурс.
Обычные сборки и подписание лучше разделять не только из соображений безопасности. У них различаются требования к Keychain, журналам, срокам хранения и допустимому восстановлению. При переполнении общего узла обычные задачи могут вытеснить данные, необходимые для выпуска.
FAQ: решения для переполненного Mac Agent
С чего начинать очистку Jenkins Mac Agent
Начинайте не с самой большой папки, а с исключения узла из новых задач и фиксации состояния. Затем отдельно проверьте Remote FS, пользовательскую Library, временные данные и архивы. Сопоставьте каталоги с активными процессами и заданиями. Workspace можно очищать только после подтверждения, что он не используется и полностью восстанавливается.
Можно ли удалять Jenkins Workspace после каждой сборки
Да, если Pipeline действительно не использует Workspace после завершения стадии: артефакты уже опубликованы, отчёты сохранены, а повторный запуск может получить исходники заново. Для этого применяйте cleanWs или аналогичную политику жизненного цикла, тестируя её сначала на отдельной ветке. Параллельные задания и повторные попытки требуют отдельной проверки.
Что делать с DerivedData и файлами симуляторов
Разделяйте эти данные. DerivedData обычно можно пересоздать, но удаление вызывает полную повторную компиляцию. Simulator Runtime и платформенные компоненты могут потребовать повторной загрузки, поэтому сначала проверьте список SDK и доступность источника. Активный симулятор и данные текущего теста нельзя удалять без остановки процесса и подтверждения владельца тестовой матрицы.
Почему Mac Agent снова заполняется после очистки
Нужно сравнить скорость роста, а не только результат одной уборки. Причиной могут быть старые ветки, каталоги параллельных запусков, дубли кэшей, архивы, логи или высокий параллелизм. Если после нескольких циклов очистки узел снова быстро достигает запрета на приём задач, добавьте данные о пиковом потреблении и времени восстановления в расчёт ёмкости.
Как принять подписанную сборку после очистки
Выполните checkout, восстановите зависимости, запустите обычную сборку и тесты, затем проведите подписанный выпуск в том же окружении. Проверьте артефакт, журнал, dSYM, Keychain и повторный запуск Agent. Возвращайте узел в общий пул только после успешного реального сценария. Простого подтверждения свободного места недостаточно.
Проведите безопасную очистку и приёмку
Используйте такой порядок, чтобы не смешивать диагностику с удалением:
- Переведите Agent в режим, при котором новые задачи не назначаются. Дождитесь завершения или корректной отмены активных процессов.
- Сохраните снимок
df, список крупных каталогов, состояние Jenkins и перечень задач, которые были на узле. - Зафиксируйте пути-кандидаты на удаление, владельцев, процессы и способ восстановления. Не включайте Keychain, активные Workspace, архивы и подписанные материалы в общий список.
- Удалите только один класс данных за раз. После каждого действия повторите измерение и проверьте, действительно ли изменилось доступное место.
- Запустите checkout исходников и восстановление зависимостей. Если компонент Xcode был удалён, проверьте его возврат до выполнения полной сборки.
- Выполните обычную сборку, тесты и проверку артефактов. Затем отдельно запустите подписанную публикацию.
- Перезапустите Agent или соответствующие службы в принятом для вашей инфраструктуры порядке. Убедитесь, что узел снова виден Jenkins и мониторинг получает корректные значения.
- Верните узел в общий пул только после успешной производственной проверки и записи результата в журнал изменений.
Для подписанных релизов дополнительно подтвердите, что очистка не затронула разрешённые ключи, профили и доступ к хранилищу. Вопросы распространения и выпуска приложения проверяйте по официальной документации Xcode о публикации.
Если существующий Mac Agent продолжает часто достигать порога запрета, не превращайте ручную очистку в постоянную операцию. Это создаёт зависимость от дежурного инженера, увеличивает очередь и делает восстановление непредсказуемым. При такой картине сравните фиксированный узел, отдельный signing-контур и временное расширение через аренду Mac для командной CI-инфраструктуры.
Покупка собственного Mac даёт физический контроль, но требует закупки, доставки, ремонта, резервирования и самостоятельного обновления ёмкости. Общий локальный узел также создаёт конфликт между обычными сборками и релизной подписью. Облачная виртуальная среда может не повторять поведение реального Mac и усложнить доступ к нужным компонентам. Для временного пика, миграции или проверки новой матрицы Xcode аренда у MACCOME позволяет добавить отдельный удалённый Mac без немедленной закупки ещё одного устройства; перед решением проверьте требования к физическим интерфейсам, долгосрочной нагрузке, сетевой задержке и корпоративному хранению данных.