Цепочка слияния (merge train) формирует очередь из запросов на слияние в целевую ветку. Перед слиянием каждый запрос проверяется с учётом запросов, стоящих перед ним в очереди. Благодаря этому в целевую ветку попадают только изменения, проверенные с учётом порядка их слияния.

Для проверки используются пайплайны для результатов слияния (merged results pipelines). Для первого запроса в очереди такой пайплайн проверяет его изменения вместе с текущим состоянием целевой ветки. Для каждого следующего запроса также учитываются изменения из предыдущих запросов в очереди. Поэтому если запросы проходят проверки по отдельности, но их изменения несовместимы, проблема будет обнаружена до слияния в целевую ветку.

Цепочки слияния настраиваются отдельно для каждого проекта. Для каждой целевой ветки проекта используется отдельная цепочка слияния.

Принцип работы цепочки слияния

Запросы на слияние располагаются в очереди в порядке добавления. Добавленные первыми запросы находятся в начале очереди.

Обработка запросов в очереди выполняется следующим образом:

  1. Запрос на слияние, для которого включено автослияние (auto-merge), добавляется в конец очереди.
  2. Deckhouse Code создаёт для запроса временную Git-ссылку (Git-ref) и запускает для него пайплайн. Git-ref содержит состояние целевой ветки, изменения из предыдущих запросов в очереди и изменения из текущего запроса.
  3. Если пайплайн первого запроса в очереди завершается успешно, запрос сливается в целевую ветку и покидает очередь.
  4. Первым в очереди становится следующий запрос. Если после слияния предыдущего запроса состояние, для которого запускался пайплайн, стало неактуальным, Deckhouse Code пересоздаёт пайплайн для нового состояния. Пайплайны последующих запросов также пересоздаются.

Цепочка не хранится как отдельный объект. Она формируется из запросов на слияние, добавленных в очередь для одной целевой ветки проекта. Когда запрос сливается или удаляется из очереди, позиции остальных запросов пересчитываются.

Предварительные требования

Перед настройкой цепочек слияния убедитесь, что выполнены следующие требования:

  • в проекте включён механизм CI/CD;
  • конфигурационный файл CI/CD настроен на создание пайплайнов для запросов на слияние;
  • в проекте включены пайплайны для результатов слияния;
  • для изменения настроек проекта у пользователя есть роль Мейнтейнер или Владелец.

Включение цепочек слияния

Чтобы включить цепочки слияния:

  1. Откройте проект.
  2. Перейдите в «Настройки» → «Запросы на слияние».
  3. В разделе «Параметры слияния» установите флажок «Включить пайплайны с результатами слияния».
  4. Установите флажок «Включить цепочки слияния».
  5. Нажмите «Сохранить изменения».

После включения цепочек слияния становятся доступны дополнительные настройки:

НастройкаОписание
Сливать немедленно без перезапуска цепочки слиянияДобавляет варианты немедленного слияния, описанные в разделе Немедленное слияние. Настройка недоступна, если проект требует слияния в режиме fast-forward или semi-linear, а также пока установлено требование слияния через цепочку
Требовать слияния запросов только через цепочку слиянияОтклоняет все прямые слияния в проекте. Подробнее — в разделе Обязательное слияние через цепочку
Максимальное количество параллельных пайплайнов на цепочку слиянияОграничивает количество одновременно выполняемых пайплайнов цепочки. Подробнее — в разделе Ограничение параллельных пайплайнов

Снятие флажка «Включить цепочки слияния» не очищает существующую очередь сразу. Очередь освобождается по мере того, как цикл обновления доходит до каждого запроса, поэтому некоторое время после сохранения настройки они могут по-прежнему отображаться в очереди.

Работа с очередью

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

Добавление запроса на слияние в цепочку

Добавить запрос на слияние в цепочку можно через веб-интерфейс или API.

  • Добавление через веб-интерфейс
  • Добавление через API

Чтобы добавить запрос на слияние в цепочку, нажмите «Установить автоматическое слияние» на странице запроса. Если в проекте включены цепочки слияния, запрос будет добавлен в цепочку вместо прямого слияния.

В зависимости от состояния запроса доступен один из следующих вариантов:

ВариантОписание
Добавить в цепочку слиянияЗапрос сразу добавляется в очередь. Вариант доступен, если запрос готов к слиянию и пайплайн для текущего HEAD SHA завершён
Добавить в цепочку слияния после прохождения всех проверок слиянияЗапрос добавляется в очередь после успешного прохождения проверок

Вариант, который будет использован, отображается рядом с кнопкой слияния. Если запрос уже проверялся пайплайном цепочки слияния, отображается текст «Повторно добавить в цепочку слияния».

Если последний пайплайн запроса завершился с ошибкой, перед добавлением запроса в очередь Deckhouse Code запрашивает подтверждение.

Чтобы добавить запрос на слияние в цепочку через API, выполните запрос:

curl --request POST --header "PRIVATE-TOKEN: <TOKEN>" \
  "https://<HOST>/api/v4/projects/<PROJECT_ID>/merge_trains/merge_requests/<MERGE_REQUEST_IID>"

Где:

  • <TOKEN> — токен для аутентификации в Deckhouse Code;
  • <HOST> — адрес экземпляра Deckhouse Code;
  • <PROJECT_ID> — идентификатор проекта;
  • <MERGE_REQUEST_IID> — внутренний идентификатор запроса на слияние в проекте.

В запросе можно указать следующие параметры:

ПараметрОписание
shaSHA, который вы ожидаете увидеть в исходной ветке. Если текущий SHA не совпадает с указанным, запрос отклоняется
squashОбъединяет коммиты исходной ветки в один при слиянии запроса. При слиянии через цепочку также учитывается настройка squash самого запроса на слияние
auto_mergeДобавляет запрос в очередь только после успешного прохождения проверок слияния

Возможные коды ответа:

КодОписание
201Запрос на слияние добавлен в очередь
202Запрос ожидает прохождения проверок слияния и ещё не добавлен в очередь
400Цепочки слияния отключены в проекте или текущее состояние запроса не позволяет добавить его в очередь
401Запрос выполнен без аутентификации
403Роль пользователя не позволяет просматривать цепочку или сливать этот запрос
404Проект или запрос на слияние не найден
409Для запроса на слияние уже включено автослияние

Просмотр цепочки слияния

Получить информацию о цепочке можно через веб-интерфейс или API.

  • Просмотр через веб-интерфейс
  • Просмотр через API

Открыть страницу цепочек слияния проекта можно одним из следующих способов:

  • на странице запроса на слияние, добавленного в очередь, перейдите по ссылке «Просмотреть цепочку слияния»;
  • на странице пайплайна цепочки слияния перейдите по ссылке «Просмотр деталей цепочки слияния» в заголовке страницы;
  • откройте страницу напрямую по адресу https://<HOST>/<NAMESPACE>/<PROJECT>/-/merge_trains.

На странице цепочек слияния отображаются:

  • фильтр для выбора целевой ветки. Изначально выбрана ветка проекта по умолчанию.
  • вкладка «Активные» с запросами на слияние, которые находятся в очереди, и вкладка «Слитые» с уже слитыми запросами. На каждой вкладке указано количество запросов;
  • информация о каждом запросе на слияние: статус пайплайна, заголовок, время добавления в очередь или слияния, а также пользователь, который добавил или слил запрос.

Пока запрос на слияние находится в очереди, его позиция отображается на странице запроса:

  • для первого запроса — «Запущена новая цепочка слияния, и этот запрос на слияние стоит первым в очереди»;
  • в остальных случаях отображается позиция в очереди, например, «Этот запрос на слияние занимает позицию 2 из 5 в очереди».

Чтобы получить информацию о цепочках слияния через API, выполните один из следующих запросов:

# Все цепочки проекта.
curl --header "PRIVATE-TOKEN: <TOKEN>" \
  "https://<HOST>/api/v4/projects/<PROJECT_ID>/merge_trains"

# Цепочка одной целевой ветки.
curl --header "PRIVATE-TOKEN: <TOKEN>" \
  "https://<HOST>/api/v4/projects/<PROJECT_ID>/merge_trains/<TARGET_BRANCH>"

# Статус одного запроса на слияние в очереди.
curl --header "PRIVATE-TOKEN: <TOKEN>" \
  "https://<HOST>/api/v4/projects/<PROJECT_ID>/merge_trains/merge_requests/<MERGE_REQUEST_IID>"

Где:

  • <TOKEN> — токен для аутентификации в Deckhouse Code;
  • <HOST> — адрес экземпляра Deckhouse Code;
  • <PROJECT_ID> — идентификатор проекта;
  • <TARGET_BRANCH> — имя целевой ветки;
  • <MERGE_REQUEST_IID> — внутренний идентификатор запроса на слияние в проекте.

Первые два эндпоинта принимают следующие параметры:

ПараметрОписание
scopeОграничивает ответ запросами, которые ещё стоят в очереди (active), или уже покинули её (complete)
sortЗадаёт порядок запросов по их позиции в очереди: asc — от самых старых к новым, desc — от самых новых к старым. Значение по умолчанию — desc

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

Получить информацию о цепочках слияния и очередях проекта также можно через GraphQL API.

Удаление запроса на слияние из цепочки

Чтобы удалить запрос на слияние из цепочки, используйте один из следующих способов:

  • отмените автослияние на странице запроса;
  • на странице цепочек слияния нажмите значок удаления в строке запроса, затем нажмите «Удалить из цепочки слияния».

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

Запрос нельзя удалить из цепочки, если его слияние уже началось. В этом случае Deckhouse Code отклоняет удаление и завершает слияние запроса.

Deckhouse Code также автоматически удаляет запрос из цепочки, если он больше не может быть слит. Подробнее — в разделе Запрос на слияние удалён из цепочки.

Немедленное слияние

Запрос на слияние можно слить немедленно, не дожидаясь его очереди в цепочке. Немедленное слияние доступно через веб-интерфейс и API.

  • Слияние через веб-интерфейс
  • Слияние через API

Если в проекте включена настройка «Сливать немедленно без перезапуска цепочки слияния», на странице запроса в очереди рядом с кнопкой слияния доступны два дополнительных варианта:

ВариантОписание
Слить сейчас и перезапустить цепочкуЗапрос сливается немедленно, а пайплайны следующих за ним запросов пересоздаются с учётом слитых изменений
Слить сейчас без перезапуска цепочкиЗапрос сливается немедленно, а существующие пайплайны продолжают выполняться без перезапуска. В результате запросы, уже находящиеся в очереди, не проверяются вместе со слитыми изменениями

Используйте вариант «Слить сейчас без перезапуска цепочки» только если слитые изменения не могут повлиять на запросы, находящиеся в очереди.

Оба варианта требуют подтверждения и позволяют выполнить слияние вне установленного порядка очереди.

Варианты немедленного слияния недоступны, если в проекте включено обязательное слияние через цепочку. Настройка «Сливать немедленно без перезапуска цепочки слияния» также недоступна, если для проекта требуется слияние в режиме fast-forward или semi-linear.

Результат немедленного слияния зависит от выбранного варианта:

  • при слиянии без перезапуска цепочки запрос отображается на вкладке «Слитые» со статусом skip_merged;
  • при слиянии с перезапуском цепочки запрос сливается напрямую и не отображается на вкладке «Слитые». После слияния он удаляется из очереди, а удаление записывается в историю активности запроса.

Для немедленного слияния через API используйте эндпоинт слияния с параметром skip_merge_train:

curl --request PUT --header "PRIVATE-TOKEN: <TOKEN>" \
  "https://<HOST>/api/v4/projects/<PROJECT_ID>/merge_requests/<MERGE_REQUEST_IID>/merge?skip_merge_train=true"

Где:

  • <TOKEN> — токен для аутентификации в Deckhouse Code;
  • <HOST> — адрес экземпляра Deckhouse Code;
  • <PROJECT_ID> — идентификатор проекта;
  • <MERGE_REQUEST_IID> — внутренний идентификатор запроса на слияние в проекте.

Параметр skip_merge_train принимает следующие значения:

ЗначениеОписание
trueЗапрос сливается немедленно без перезапуска цепочки
falseЗначение по умолчанию. Запрос сливается немедленно, а пайплайны следующих за ним запросов пересоздаются

Параметр действует только при включённой настройке «Сливать немедленно без перезапуска цепочки слияния». В остальных случаях параметр игнорируется. Если в проекте включено обязательное слияние через цепочку, запрос на слияние отклоняется.

Настройка цепочки слияния

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

Обязательное слияние через цепочку

Чтобы запретить прямое слияние запросов в проекте, установите флажок «Требовать слияния запросов только через цепочку слияния».

После включения этой настройки:

  • варианты немедленного слияния становятся недоступны;
  • запрос на слияние через API отклоняется, если для него не включено автослияние и он не добавлен в цепочку;
  • слияния, которые выполняет сама цепочка, продолжают работать без изменений.

При включении обязательного слияния настройка «Сливать немедленно без перезапуска цепочки слияния» автоматически отключается и становится недоступна. После сохранения настроек с включённым обязательным слиянием эта настройка остаётся отключённой, в том числе после отключения обязательного слияния. Чтобы снова использовать её, включите настройку заново.

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

Ограничение распространяется на всех пользователей, включая владельцев проекта и администраторов.

Ограничение параллельных пайплайнов

Для нескольких запросов в цепочке пайплайны могут выполняться одновременно. Количество одновременно выполняемых пайплайнов определяется двумя ограничениями:

  • ограничением экземпляра Deckhouse Code, которое задаёт администратор. По умолчанию — 20;
  • настройкой проекта «Максимальное количество параллельных пайплайнов на цепочку слияния».

Используется меньшее из этих двух значений. Например, если для экземпляра установлено ограничение 20, а для проекта — 10, одновременно могут выполняться не более 10 пайплайнов.

Чтобы использовать ограничение экземпляра, оставьте настройку проекта пустой. Для проекта можно указать значение от 1 до 500, но оно не может увеличить ограничение, установленное для экземпляра.

Пайплайны цепочки слияния

Для каждого запроса в очереди Deckhouse Code запускает пайплайн для Git ref. Такой пайплайн выполняется не для исходной ветки запроса. В списке пайплайнов он помечается как merge train, что позволяет отличить его от обычного пайплайна для результатов слияния.

Завершённый пайплайн цепочки слияния нельзя перезапустить, поскольку состояние репозитория, для которого он выполнялся, могло измениться. Чтобы запустить новый пайплайн, повторно добавьте запрос на слияние в цепочку.

Пайплайн пересоздаётся в следующих случаях:

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

Запуск заданий только в пайплайнах цепочки слияния

В пайплайне цепочки слияния переменная CI_MERGE_REQUEST_EVENT_TYPE имеет значение merge_train. С её помощью можно запускать задание только в пайплайнах цепочки слияния:

integration-tests:
  script: ./run-integration-tests.sh
  rules:
    - if: $CI_MERGE_REQUEST_EVENT_TYPE == "merge_train"

Чтобы, наоборот, пропускать задание в пайплайнах цепочки, используйте обратное условие:

quick-lint:
  script: ./lint.sh
  rules:
    - if: $CI_MERGE_REQUEST_EVENT_TYPE != "merge_train"

Статусы запросов в очереди

Для каждого запроса на слияние в цепочке определяется статус, который можно получить через REST API или GraphQL API. В веб-интерфейсе статусы напрямую не отображаются: запросы распределяются между вкладками «Активные» и «Слитые».

СтатусОписание
idleЗапрос находится в очереди, пайплайн ещё не запущен
freshПайплайн соответствует текущему результату слияния
staleСостояние цепочки изменилось, пайплайн пересоздаётся
mergingВыполняется слияние запроса
mergedЗапрос слит через цепочку и удалён из очереди
skip_mergedЗапрос слит немедленно без перезапуска цепочки и удалён из очереди

Запросы на слияние со статусами idle, fresh и stale отображаются на вкладке «Активные», их можно удалить из очереди. Запросы со статусами merged и skip_merged отображаются на вкладке «Слитые». Запрос со статусом merging не отображается ни на одной из вкладок до завершения слияния.

Активность запроса на слияние

Deckhouse Code записывает, что происходит с запросом на слияние в цепочке, в виде системных заметок в разделе «Активность» запроса. Фиксируются следующие события:

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

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

Доступ к цепочкам слияния

Доступные действия с цепочками слияния зависят от роли пользователя и настроек проекта:

ДействиеТребования
Просмотр страницы цепочек слияния и просмотр информации через APIВ проекте включены цепочки слияния, и у пользователя есть доступ на чтение запросов на слияние и пайплайнов. В стандартных ролях это доступно пользователям с ролью Наблюдатель или выше
Получение статуса цепочки для отдельного запроса на слияниеТе же требования, что и для просмотра цепочки
Добавление запроса на слияние в цепочкуУ пользователя есть право на слияние этого запроса. В стандартных ролях это доступно пользователям с ролью Разработчик или выше
Удаление запроса на слияние из очереди на странице цепочекУ пользователя есть право на отмену пайплайнов, изменение запроса на слияние и слияние в целевую ветку. В стандартных ролях это доступно пользователям с ролью Разработчик или выше
Изменение настроек цепочек слияния в проектеРоль Мейнтейнер или Владелец

Для просмотра цепочек слияния через веб-интерфейс или API требуется аутентификация. Анонимным пользователям цепочки недоступны даже в публичных проектах.

События аудита

Deckhouse Code записывает следующие события аудита при изменении настроек цепочек слияния в проекте:

Событие аудитаОписание
project_cicd_merge_trains_enabled_updatedИзменена настройка включения цепочек слияния в проекте
project_cicd_merge_train_enforced_updatedИзменена настройка обязательного слияния через цепочку

Устранение проблем

Ниже описаны распространённые проблемы при работе с цепочками слияния и способы их устранения.

Запрос на слияние удалён из цепочки

Если во время выполнения пайплайна запрос больше не может быть слит, Deckhouse Code удаляет его из очереди, чтобы не блокировать остальные запросы. Причина удаления указывается в системной заметке в разделе «Активность».

Наиболее частые причины удаления:

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

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

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

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

Устраните причину, указанную в системной заметке, и повторно добавьте запрос в цепочку.

Кнопка слияния не предлагает варианты цепочки слияния

Проверьте следующее:

  • в настройках проекта включены пайплайны с результатами слияния и цепочки слияния;
  • конфигурационный файл CI/CD создаёт пайплайны для запросов на слияние;
  • у запроса на слияние есть пайплайн для текущего HEAD SHA исходной ветки, и этот пайплайн завершён;
  • роль пользователя позволяет слить этот запрос.

Слияние отклонено в проекте, требующем цепочку слияния

Если включена настройка «Требовать слияния запросов только через цепочку слияния», прямое слияние отклоняется, в том числе через API. Вместо этого добавьте запрос на слияние в цепочку.

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

Пайплайн цепочки слияния нельзя перезапустить

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

Слияние выглядит зависшим

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

Цепочки слияния отключены, но очередь всё ещё отображается

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

Страница цепочек слияния пуста

Проверьте следующее:

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

Действие удаления недоступно

Удалить запрос из цепочки можно только на вкладке «Активные» и при наличии прав на отмену пайплайнов, изменение запроса на слияние и слияние в целевую ветку.

Запрос нельзя удалить из цепочки, если его слияние уже началось.