Монорепозиторий в GitLab CI: запускаем проверки по изменённым каталогам

В монорепозитории рядом живут API, worker и документация. После исправления опечатки запускаются обе сборки, а после изменения общей библиотеки хочется проверить оба сервиса. Простой фильтр по каталогу сервиса уменьшает лишнюю работу, но легко пропускает общую зависимость. Сначала нужно описать, какие файлы способны изменить результат каждой проверки.

Для API это могут быть services/api, libs/common и общий lock-файл. Для worker — собственный каталог, та же библиотека и тот же lock-файл. CI-конфигурация тоже влияет на выполнение, поэтому её изменение полезно включить в оба набора. Rules:changes добавляет job при совпадении хотя бы одного изменённого пути.

Проверки для merge request

Следующий .gitlab-ci.yml предназначен для MR pipelines. Пример проверяет синтаксис Python через compileall, поэтому эти каталоги должны существовать в репозитории. Он не подменяет тесты проекта: реальные тестовые команды можно добавить после выбора нужной job.

workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_PIPELINE_SOURCE == "schedule"'

default:
  image: python:3.12-alpine

api_check:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      changes:
        - services/api/**/*
        - libs/common/**/*
        - requirements.lock
        - .gitlab-ci.yml
  script: python -m compileall -q services/api libs/common

worker_check:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      changes:
        - services/worker/**/*
        - libs/common/**/*
        - requirements.lock
        - .gitlab-ci.yml
  script: python -m compileall -q services/worker libs/common

metadata_check:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
  script: test -n "$CI_COMMIT_SHA"

При изменении только services/api запускаются api_check и metadata_check. Изменение libs/common включает обе проверки сервисов. Изменение docs оставляет только metadata_check: это сохраняет непустой pipeline даже когда сервисные jobs не нужны. Периодическое расписание запускает обе проверки целиком через первое правило.

Относительно чего определено changes

В MR pipeline GitLab сравнивает изменения с целевой веткой MR. В branch pipeline обычного push используется предыдущий commit ветки. Поэтому одна и та же строка changes может включать разные jobs при разных источниках. Это относится к выбору набора проверок, а не к запуску двух pipelines на один push.

Для нового branch pipeline и сценариев без push, например расписания, стандартная база сравнения может отсутствовать, и changes способно сработать неожиданно широко. В примере расписание выделено явно, поэтому поведение читается без догадок. Если нужны только отличия от main, укажите changes:compare_to с нужным ref и проверьте этот сценарий отдельно.

Compare_to с refs/heads/main означает выбранную политику сравнения с main, а не универсальное исправление. Для долгоживущей feature-ветки оно будет учитывать накопленный diff. Для merge results и fork-сценариев база имеет дополнительные особенности. Сначала определите требуемый смысл проверки, затем фиксируйте ref.

Общая зависимость важнее удобного каталога

Если API импортирует код из libs/common, проверка только services/api пропустит изменения библиотеки. Аналогично влияют общий Dockerfile, lock-файл, генератор клиентов и схема API. Постройте короткую карту зависимостей для каждой job и переведите её в paths. Наличие общего файла не означает, что обязательно нужны все тяжёлые проверки: можно выделить отдельный тест контракта, если он действительно покрывает влияние.

Пути задаются относительно корня репозитория. Не добавляйте ./ и не рассчитывайте на shell-раскрытие glob: сопоставление выполняет GitLab до Runner. При очень больших diff и множестве шаблонов учитывайте лимиты проверки patterns; широкое срабатывание в таком случае безопаснее пропуска, но может объяснить внезапную полную сборку.

Проверим четыре осмысленных изменения

Создайте тестовые MR по одному изменению: файл API, файл worker, общая библиотека и документация. Сравните состав jobs с ожидаемой картой, затем запустите расписание. Отдельно измените CI-файл, чтобы убедиться, что сам механизм проверок получает проверку после правки.

После настройки экономия возникает из явной зависимости между файлами и проверками. Когда появляется новый общий модуль, обновляйте эту карту одновременно с кодом. Иначе зелёный pipeline будет означать только то, что выбранные jobs прошли, а нужная проверка могла вообще не попасть в граф.

Ещё по теме

Продолжить изучение

Хотите собрать проверяемый путь от коммита до релиза? Jobs, runners, артефакты и деплой — темы программы «GitLab CI/CD: автоматизация сборки и деплоя».

Продолжить на практике

  • GitLab CI/CD: автоматизация сборки и деплоя ↗

    От первого .gitlab-ci.yml до pipeline, который тестирует код, собирает образ и выкладывает приложение. Runners, artifacts, cache, registry, окружения и безопасный откат — на одном практическом проекте.