Можно ли принять код?
Линтер, модульные и интеграционные тесты. Ошибка должна блокировать слияние.
MR · MERGE · RELEASE
Повтор нужен, если он проверяет другой код, сборку или окружение. Сам факт merge ещё не повод запускать всё заново.
Здесь master — основная ветка. В CI её имя берётся из CI_DEFAULT_BRANCH.
В master попал непроверенный результат слияния, либо появились условия, которых не было в MR.
Конечный код уже проверен перед merge, а тесты и все существенные входные данные совпадают.
Линтер, модульные и интеграционные тесты. Ошибка должна блокировать слияние.
Проверки пакета, образа и доступных только здесь интеграций. Ошибка блокирует выкладку.
Проверка запуска, доступности и ключевого сценария в реальном окружении.
| Ситуация | Тесты после merge | Почему |
|---|---|---|
| Строгий Fast-forward, проверен конечный коммит | Можно убрать повтор | В master тот же код. Условия — ниже. |
| Ветки разошлись; проверялись только исходные ветки MR | Нужны для результата | Комбинация изменений ещё не проверена. Лучше проверить её до merge. |
| Автоматический rebase при merge, результат не проверен очередью | Нужны для результата | GitLab не перезапускает CI на результате такого rebase. [1] |
| Squash или новый merge-коммит | Зависит от сборки | Новый SHA сам по себе не означает новый код. Важны содержимое и использование Git-метаданных. |
| Перед merge проверен актуальный общий результат | Можно убрать повтор | Если содержимое, сборка и окружение эквивалентны проверенным. |
| Другой образ, зависимости, переменные или внешние сервисы | Нужны целевые проверки | Тестируется новое условие. Повторять весь набор автоматически незачем. |
Если текущий master — предок проверенного коммита MR, Git может передвинуть master на него. Без squash и rebase при слиянии новый коммит не появляется. [1]
Если master ушёл вперёд и ветки разошлись: обновить ветку MR, проверить новый результат, затем сливать. Сам Fast-forward не знает о тестах — обязательность CI задаётся отдельно.
Пример: размер очереди ограничен 500 элементами. Две настройки лежат в разных файлах, поэтому Git может объединить изменения без текстового конфликта.
| Версия | workers | batch_size | Произведение |
|---|---|---|---|
| Исходная | 2 | 100 | 200 ✓ |
| Только MR A | 4 | 100 | 400 ✓ |
| Только MR Б | 2 | 200 | 400 ✓ |
| A + Б | 4 | 200 | 800 — ошибка |
from workers import WORKERS
from batches import BATCH_SIZE
def test_queue_fits():
assert WORKERS * BATCH_SIZE <= 500Обновление MR выявит проблему, если такой тест есть. Отсутствие конфликтов Git не доказывает совместимость поведения.
SHA меняется, но дерево файлов может остаться тем же. Для тестов, зависящих только от файлов и фиксированных входов, повтор может быть лишним. Если сборка использует SHA, историю, теги или имя ветки — проверь полученный артефакт.
# Подставь SHA проверенного и влитого коммитов.
git diff --exit-code "$TESTED_SHA" "$MERGED_SHA" --Код возврата 0 означает одинаковые отслеживаемые файлы. Это не проверка зависимостей, переменных или внешнего состояния и не самостоятельная блокировка merge.
Для схемы «тесты кода только в MR» нужны все условия ниже. Это рабочая дисциплина для обычного процесса слияния, а не гарантия отсутствия ошибок в программе.
Settings → Merge requests: Fast-forward merge; squash — Do not allow; Enable automatic rebase prior to merge — выключено. После обновления ветки дождаться нового успешного CI. [1]
Защитить ветку: Allowed to push and merge — No one; force push выключен. Право сливать MR задать отдельно через Allowed to merge. Проверить пересекающиеся правила доступа. [5]
Совпадают тесты, файлы, версии зависимостей, образ среды исполнения, параметры и значимое внешнее состояние. Фиксируй зависимости и образы по digest; одинаковый SHA не делает окружения одинаковыми.
Проверки с защищёнными переменными и отдельной релизной сборкой могут оставаться после merge. Доступ к таким переменным в MR зависит от защиты веток и настроек проекта. [6]
Примеры для Python. Выбери схему под свой процесс. Проверки релиза здесь обозначены отдельным скриптом проекта.
При выполнении условий выше в master остаются проверки релиза.
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
- when: never
stages: [test, release_check]
default:
image: python:3.12-slim
tests:
stage: test
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
script:
- python -m pip install --require-hashes -r requirements-ci.txt
- python -m pytest -q
allow_failure: false
release_check:
stage: release_check
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
script:
- ./ci/verify-release.sh
allow_failure: falserequirements-ci.txt должен содержать pytest, зависимости проекта и транзитивные зависимости с версиями и хешами. Тег python:3.12-slim дан для читаемости: в рабочем CI закрепи одобренный образ по digest.
verify-release.sh — твой скрипт сборки и проверки пакета/образа. Его нужно реализовать. Выкладывай именно проверенный артефакт; при ошибке скрипт должен завершаться ненулевым кодом. Если релиза нет, убери это задание и правило master в workflow.
Оставь workflow, этапы и release_check из A. Замени задание tests этим:
tests:
stage: test
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
script:
- python -m pip install --require-hashes -r requirements-ci.txt
- python -m pytest -q
allow_failure: falseТесты выполняются в MR и при push в master. В master этап release_check начнётся только после успешных тестов.
Сохрани схему A: её правило merge_request_event допускает и merged results, и merge train pipelines. В Settings → Merge requests включи Enable merged results pipelines и Enable merge trains. YAML сам очередь не включает. [3]
Если дорогая проверка нужна только общему результату, добавь отдельное задание:
combined_tests:
stage: test
rules:
- if: '$CI_MERGE_REQUEST_EVENT_TYPE == "merged_result" || $CI_MERGE_REQUEST_EVENT_TYPE == "merge_train"'
script:
- python -m pip install --require-hashes -r requirements-ci.txt
- python -m pytest -q integration/
allow_failure: falseintegration/ — отдельный набор тестов проекта. В задании tests из A замени команду на python -m pytest -q --ignore=integration/, чтобы не запускать этот набор дважды. Значения CI_MERGE_REQUEST_EVENT_TYPE описаны в документации. [8]
Оставь обязательность CI и защиту master. Проводи слияния через очередь, без обхода. Убирать повтор в master можно при эквивалентности проверенного кода, сборки и условий; проверка релиза сохраняет свою задачу.
Во всех примерах workflow разрешает только MR и push в основную ветку. Теги, расписания, API и ручной запуск отдельного branch pipeline не включены. Нужные события добавляй явно. Это также убирает лишний branch pipeline при push в ветку MR. [9]
| Возможность | Тариф | Что проверяется |
|---|---|---|
| Обычный MR pipeline | Free | Исходная ветка MR. Актуальный master автоматически не подмешивается. [6] |
| Fast-forward + обязательный CI + защита ветки по ролям | Free | Позволяет требовать проверку обновлённой ветки перед слиянием. [1] [4] [5] |
| Merged results pipeline | Premium / Ultimate | Временный коммит: MR + целевая ветка. Другие ожидающие MR не учитываются. [2] |
| Merge trains | Premium / Ultimate | MR + целевая ветка + предыдущие MR в очереди. [3] |
Очередь нужна для совместимости параллельных MR. Merged results pipeline сам по себе не закрывает гонку двух слияний. При текстовом конфликте GitLab может запустить обычный MR pipeline вместо merged results — проверяй тип. [2] [3]
Free означает доступность функции, а не бесплатные вычисления: runners и лимиты CI считаются отдельно. Для Self-Managed важны и лицензия, и установленная версия. Auto-merge лишь ждёт обязательные проверки; сам по себе он не создаёт merge train. [4]
ЧТО УДАЛЯТЬ ИЗ CI
Для каждого повторного задания спроси: «Какое новое условие оно проверяет?» Если никакое — убирай после проверки настроек. Если ответ «общий результат ещё не тестировали» — перенеси эту проверку до merge, когда процесс это позволяет.
Факты о функциях и тарифах — из GitLab Docs. Разделение проверок и примеры CI — инженерные рекомендации для описанных условий.