Сборка - это заранее подготовленное состояние машины: репозитории получены, зависимости установлены, кэши прогреты. Успешная сборка становится активной и служит основой для запусков; неудачная не заменяет последнюю успешную. Это простое правило даёт важное свойство - неудачная попытка обновить окружение не ломает работу тем, кто запускает задачи прямо сейчас. Обратная сторона того же правила: пока новая сборка не прошла, агенты продолжают работать на старом описании, и расхождение между тем, что в репозитории, и тем, что на машине, надо замечать самому.
В панели управления доступно больше, чем кажется на первый взгляд: журналы, закрепление конкретной активной сборки, запуск агента из выбранной версии и восстановление предыдущей конфигурации окружения. Всё это - инструменты воспроизводимости. Возможность запустить задачу на вчерашней сборке превращает вопрос а когда это сломалось из догадки в эксперимент.
Полезно один раз оформить критерии готовности сборки как чек-лист. Ниже он и приведён: установка завершилась успешно и повторяется идемпотентно, все репозитории на ожидаемых ссылках, версии инструментов и системных пакетов зафиксированы, сервисы запускаются отдельно от установки, сфокусированный тест проходит без ручной донастройки, в журналах нет секретов и существует предыдущая успешная сборка для отката.
Последние два пункта чаще всего пропускают, и оба дорого обходятся. Журналы сборки читают люди и хранят системы; секрет, случайно напечатанный в процессе установки, оказывается в месте, о котором вы не думали, и отзывать его придётся так же, как утёкший в публичный репозиторий. А отсутствие предыдущей успешной сборки означает, что откатываться некуда: любая неудачная правка окружения останавливает всю автономную работу до тех пор, пока вы её не почините.
Отдельная тема - снимки состояния. Они удобны и потому опасны: вместе с полезным состоянием в снимок может попасть случайно созданный локальный файл переменных окружения. Рекомендуемый канал для секретов - отдельное хранилище панели управления, а не файл, оказавшийся на диске в момент снятия. Это ровно тот случай, когда удобство и безопасность расходятся, и выбирать нужно осознанно.
У снимков есть и срок жизни: при длительном бездействии они истекают автоматически, и каждый запуск или возобновление продлевает окно; корпоративная политика хранения эту границу не двигает. Практический вывод простой - снимок не является архивом. Всё, что должно пережить месяцы, живёт в репозитории и в описании окружения, а не в состоянии машины, которое система вправе переработать.
Возможность запустить задачу на выбранной сборке стоит разобрать как приём, а не как пункт интерфейса. Когда автономные прогоны вдруг начинают падать на одном и том же шаге, вопрос всегда один: изменился код или изменилось окружение. Ответ получают за два запуска - та же задача на текущей сборке и на последней, где всё работало. Если на старой она проходит, дело в окружении, и разбор сужается до различий между двумя описаниями. Если падает на обеих, окружение ни при чём, и дальше смотрят на код и на внешние сервисы. Это тот же приём, что и поиск сломавшего коммита, только применённый к среде.
У закрепления сборки есть цена, и о ней стоит помнить, чтобы приём не превратился в проблему. Пока проект живёт на старой закреплённой сборке, он накапливает расхождение: версии инструментов, системные пакеты, базовый образ уходят вперёд, а машина остаётся. Это разумная временная мера на время инцидента и плохая постоянная политика, потому что возвращение стоит тем дороже, чем дольше откладывалось. Признак, по которому в реальной работе понимают, что расхождение зашло далеко, - обновление окружения, которое падает не на одном шаге, а сразу на нескольких несвязанных.
Инженерный вывод: сборка - это версия вашей среды, и обращаться с ней стоит как с версией. Закрепление активной сборки, наличие предыдущей успешной, чистые журналы и воспроизводимая установка дают то же, что даёт тег в репозитории: возможность вернуться в известное хорошее состояние без археологии.
Типичные провалы предсказуемы. Обновить окружение без предыдущей успешной сборки и остаться без отката. Оставить секреты в журналах установки. Хранить нужное в снимке, который истечёт. Закрепить сборку на время инцидента и забыть про это на полгода. И считать успешную сборку доказательством работоспособности, не прогнав хотя бы один сфокусированный тест.
Готовая к работе сборка
[ ] установка завершилась успешно и повторный запуск идемпотентен
[ ] все репозитории получены на ожидаемых ссылках
[ ] версии инструментов и системных пакетов зафиксированы
[ ] сервисы запускаются отдельно от установки
[ ] сфокусированный тест проходит без ручной донастройки
[ ] в журналах сборки нет секретов
[ ] есть предыдущая успешная сборка для отката