Деплой по тегу: где рвётся релизный контур
Написал в поле «ветка» слово main и нажал «запустить» — типовой способ выпустить релиз. Но ветка — не версия, а движущаяся ссылка: пока идёт сборка, в неё уже влит следующий набор изменений, и на стенде оказывается не то, что было в коде на момент старта. Воспроизводимость сборки ломается и внутри: зависимости подтягиваются из сети без фиксации, и повторный запуск из того же коммита даёт другой результат.
Расхождение замечают не сразу. Артефакт релиза собирается заново под каждое окружение, со своим набором переменных, и в продакшене оказывается сборка, которой нет ни в хранилище, ни у кого на руках. Выяснить, что именно уехало, нечем: тега нет, хеш коммита нигде не записан, журнал выпуска закрыт. Откат превращается в пересборку прошлого состояния по памяти, а пока её готовят, контур держится на ручных правках продакшена — они не проходят проверки и исчезают при следующем выпуске.
Деплой по тегу убирает эту развилку. Тег — неизменяемая метка на конкретном коммите, и артефакт собирается ровно один раз, привязывается к тегу и переиспользуется во всех окружениях: одно и то же содержимое проходит тестовый стенд и уезжает в продакшен. Разбираем, как устроить такой контур и где он всё ещё рвётся.
Что меняется после перехода на релизные метки
Пока развёртывание шло из головы ветки, признаком «что задеплоено» был последний коммит: в продакшн мог уехать срез, который никто не проверял целиком. Релизная метка снимает эту неопределённость — запуск идёт от неизменяемого указателя в Git, за которым закреплён конкретный срез кода и настроек.
Разница проявляется не в первый день, а на метриках. Вот что мы сверяем на первой же неделе после перехода, чтобы отличить реальный эффект от формального порядка:
- Доля успешных выпусков — можно ли для любого инцидента назвать точный срез, из которого собран прод, и совпадает ли он с тем, что прошло проверки.
- Время отката — есть ли метка предыдущего стабильного выпуска, на которую возвращаются одним действием: минуты против десятков минут при сборке из ветки.
- Число инцидентов из-за несоответствия кода и сборки — ушли ли случаи, когда в артефакт попадал код, которого не было в проверенном срезе.
- История выпусков — читается ли она по меткам: что вошло, когда, кто подтвердил.
- Контроль версий — защищены ли метки от перезаписи и есть ли правило, кто и как их ставит.
Если пункты закрыты, выпуск воспроизводится по метке, откат превращается в переключение на предыдущую, а разбор инцидента начинается с конкретного среза, а не с поиска «что же там было».
Сравнение: деплой по тегу, по ветке или вручную
Выбор модели выпуска определяет, что именно попадает в прод и насколько повторяем результат. Ниже — четыре варианта, которые встречаются чаще всего, с их границами применимости и ценой, которую они тянут за собой.
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| Деплой по тегу | Продуктовый контур: метка указывает на конкретное состояние кода, повторный выкат той же метки даёт тот же артефакт | Нужна дисциплина именования — лишняя метка создаёт релиз. Плохо ложится на частые мелкие правки |
| Деплой по ветке | Стенды разработки и тестирования, где нужен автоматический прогон после каждого слияния | В прод уходит «то, что накопилось»: нет явной границы релиза, откат возможен только на предыдущее состояние ветки |
| Ручной запуск релиза | Редкие регламентированные выпуски, выпуск в согласованное окно | Зависит от человека: пропустили запуск — в проде устаревшая сборка, история выкатов разрознена |
| Условный выпуск | Релиз запускается по событию: метка, изменение в отдельном каталоге, закрытие задачи | Правила разрастаются и конфликтуют между собой, их сложнее объяснить команде и проверить перед выкатом |
На практике подходы не конкурируют, а делят контуры: метка как единственный вход в прод, ветка — как быстрый отклик на стендах, ручной запуск — для исключений вроде внепланового исправления. Условный выпуск имеет смысл там, где правило простое и проверяемое — например, выпуск только при изменении каталога сервиса. Дальше показываем, как это свести в один конвейер без дублирования логики.
Конвейер релизов в CI/CD: этапы инженерной работы
Этапы внедрения одинаковы, какой бы инструмент сборки ни стоял у заказчика: сначала аудит и правила, потом автоматика. Задача — чтобы выпуск запускался тегом, а не собранным вручную пакетом: тогда версия в продакшене однозначно восстановима по идентификатору, а спор «что там сейчас развёрнуто» исчезает.
- Аудит конвейера. Инвентаризация веток, тегов и ручных шагов: где собирается артефакт, как он попадает в окружения, какие операции делаются руками. На выходе — карта расхождений между сборкой и выпуском.
- Схема версионирования. Фиксируем формат тега (major.minor.patch и отдельный префикс для предрелизов) и правило, какой тег ведёт в тестовый контур, а какой — в продуктивный.
- Правила выпуска. Защищённые теги, права на их создание, обязательные проверки до публикации, ручное подтверждение на продуктив.
- Настройка сборки из тега. Один тег — один неизменяемый артефакт, который не пересобирается при продвижении между окружениями.
- Настройка релизов на деплой. Привязка тега к окружению, миграции базы, проверка живости после выката и автоматический откат на предыдущий тег при неудаче.
- Репетиция. Прогон на одном сервисе: замеряем время от постановки тега до рабочего окружения и отдельно — время возврата на прошлую версию.
- Передача управления. Регламент выпуска, описание откатов и прав доступа, обучение дежурной команды заказчика.
Что остаётся у заказчика: конфигурации и регламенты
Передача проекта — это не архив с исходниками, а рабочая система, которую принимающая команда может запустить, изменить и откатить без участия автора. Поэтому к закрытию работ собирается комплект, где у каждого артефакта есть владелец и понятный сценарий использования, а не только факт наличия файла.
- Файлы конвейера — описания сборки и выпуска лежат в репозитории рядом с кодом, а не в настройках веб-интерфейса: изменения проходят ревью и версионируются вместе с приложением.
- Схема конвейера — от сборки и проверок до публикации артефакта и выкладки, с явно отмеченными точками ручного подтверждения и местами, где выпуск останавливается автоматически.
- Матрица окружений — какие ветки и теги попадают в тестовый и промышленный контуры, чем отличаются их параметры, как разделены данные и секреты.
- Политики доступа — роли на запуск выпуска и подтверждение выкладки в промышленный контур; для автоматики используются отдельные служебные учётные записи вместо личных.
- Регламент выпуска — как формируется тег, кто имеет право его поставить и что считается основанием для выпуска, включая состав обязательных проверок.
- Инструкция по откату — пошаговый возврат на предыдущий выпуск: какие команды, в каком порядке, за какое время контур возвращается в рабочее состояние и по каким признакам откат запускается.
- Документация конвейера — где хранятся секреты и как они обновляются, как подключаются зависимости, какие проверки блокирующие, а какие только предупреждают.
Комплект считается принятым не по подписи, а по факту: инженер заказчика сам ставит тег, доводит выпуск до промышленного контура и выполняет учебный откат. Замечания, найденные на этом шаге, закрываем до передачи — вместе со схемами и регламентом они остаются внутри проекта и не требуют обращений к нам за пояснениями.
Кейс: релизы по меткам вместо сборки из ветки
Продуктовая команда заказчика вела несколько сервисов и собирала релизы прямо из основной ветки. У выпуска не было неизменяемой точки: состояние среды нельзя было описать одним идентификатором, поэтому «вернуть как было» означало собрать заново — а новая сборка из той же ветки могла не совпасть с тем, что реально работало.
Перед кейсом внедрения замерили три величины за квартал: выпуск занимал от 35 до 50 минут ручных операций, каждый четвёртый релиз заканчивался откатом, а примерно в каждом пятом случае артефакт на среде не совпадал с кодом ветки — в неё успевали приехать новые коммиты.
Что изменили
Переход на метки сделал тег единственным источником релиза. Сборочный контур собирает артефакт только из помеченного коммита в Git и кладёт его в неизменяемое хранилище, а выкладка в продуктивную среду из ветки запрещена правилами. Откат — не пересборка, а переключение на предыдущую метку, той же командой, что и выпуск. Реестр меток стал журналом релизов: по одному идентификатору видно, что и когда уехало.
Результаты проекта
| Метрика | До | После |
|---|---|---|
| Время выпуска | 35–50 минут | 6–8 минут |
| Отказы выпуска | каждый четвёртый релиз | один из двадцати |
| Расхождения сборки и кода | около 20% релизов | не воспроизводятся |
| Возврат к прошлому релизу | около часа | несколько минут |
Через полгода команда стала выпускать чаще, а не реже: релиз перестал быть событием с риском, а метрики релизов теперь читаются из истории меток, а не собираются вручную по логам.
Что делать, если релиз уже собирается из ветки?
Да, переход на метки не требует переписывать конвейер. Метка и ветка — оба указателя на коммит, поэтому шаги сборки, тестов и публикации артефакта остаются прежними. Меняются две вещи: условие запуска и то, откуда берётся номер версии.
Основная работа — вынести версию из шаблона в параметр. Сейчас номер обычно вычисляется из имени ветки или проставляется вручную, и именно это мешает запуску по метке. Как только версия приходит снаружи, из самой метки, конвейер становится безразличен к источнику запуска, а переключение сводится к настройке триггера.
Внедрять это стоит постепенно, не разрывая работающую схему. Сначала запуск по метке добавляется параллельно: сборка из ветки продолжает выпускать промежуточные версии, а метка запускает релизный проход по тем же шагам. Первые релизы прогоняем в обе стороны и сравниваем артефакты — состав и контрольная сумма должны совпасть, иначе в каком-то шаге зашита зависимость от ветки.
История при этом не ломается. Метки можно проставить на уже выпущенные коммиты задним числом — старые релизы получат те же обозначения, что и новые, и связь «метка — артефакт — среда» станет непрерывной. После этого стабильные релизы уходят только по метке, а ветка остаётся инструментом разработки; вернуться к прежней схеме можно на любом этапе, пока параллельный запуск не отключён.
Финальный шаг — правило, запрещающее публикацию в прод без метки, и запрет пересборки существующей: одна метка даёт один неизменяемый артефакт. Нашли ошибку в релизе — выпускается новая метка, а не перезапись старой. Именно это делает откат предсказуемым: среда возвращается к конкретному зафиксированному артефакту.
Частые вопросы по релизным меткам и откатам
Сомнения по релизным меткам обычно сводятся к четырём темам: кто вправе выпускать, как откатиться, что с параллельными версиями и не придётся ли ломать работающую схему. Ниже — как это устроено в конвейере.
Кто имеет право ставить релизную метку?
Право на выпуск есть у ограниченного круга ролей: метку ставит ответственный, а прямая выкладка из рабочей ветки закрыта настройками конвейера. Обойти это правило нельзя — проверки выполняются независимо от того, кто выпускает.
Как откатиться, если релиз оказался плохим?
Артефакт собирается один раз и хранится неизменяемым вместе с меткой, поэтому откат релиза — это выкладка предыдущей метки, а не пересборка. Возврат к рабочей версии занимает минуты и не зависит от того, что успели поменять в ветке.
Можно ли вести несколько версий параллельно?
Да: под каждую линию поддержки своя ветка и свои метки, поэтому исправление в старой версии не тянет за собой изменения из новой. Параллельные версии живут на разных окружениях и не мешают друг другу.
Что будет с уже работающей схемой выпуска?
Доработка конвейера идёт поэтапно: старый способ остаётся рабочим, пока новый не проверен на боевом выпуске. Переключение — по одной услуге, с возможностью вернуться назад.
Как долго хранятся релизные артефакты?
Политика хранения задаётся явно: выпуски по каждой метке остаются доступными для отката, остальное уходит по расписанию. Хранилище не растёт бесконечно.
Обсудим вашу схему релизов и вернёмся с планом
Чтобы схема деплоя по тегу заработала на вашей инфраструктуре, а не осталась набором правил в отдельном репозитории, нужен план под ваш текущий процесс выпуска: как версии присваиваются сейчас, кто и в какой момент ставит релизный тег, сколько окружений проходит артефакт и что считается откатом. Опишите это в свободной форме — хватит ветвления, способа сборки и того, где сейчас ручные шаги. Наши инженеры разберут схему и вернутся с оценкой работ и планом внедрения: что делаем на старте проекта, что позже, что можно оставить как есть.
- План внедрения по этапам: разметка релизных тегов и правила их появления, сборка артефакта из зафиксированного состояния, продвижение по окружениям
- Схема отката: возврат на предыдущий тег без пересборки, с сохранением конфигурации окружения и данных
- Политики доступа и подписи: кто имеет право выпускать тег, чем подтверждается подлинность артефакта
- Разделение сборки и выката: что переиспользуется между окружениями, где остаются различия в настройках
- Набор проверок перед выкатом: какие автоматические ворота пропускают релиз, а какие требуют подтверждения
- Документация и передача: описание схемы выпуска, инструкции для дежурного, разбор типовых сбоев
Опишите задачу — вернёмся с оценкой работ и планом, где зафиксированы этапы, зоны ответственности и порядок запуска.







