Что такое only/except в GitLab CI?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое only и except в GitLab CI?
В GitLab CI/CD only и except — это два ключевых директивы, используемые для условного выполнения заданий (jobs) в конвейере. Они позволяют разработчикам точно контролировать, когда и при каких условиях должен запускаться конкретный job, что является фундаментом для создания гибких, эффективных и экономичных конвейеров. По сути, это правила фильтрации, основанные на таких событиях, как ветки, теги, Merge Request (MR) или даже произвольные переменные.
Основное назначение и принцип работы
onlyопределяет список условий, при которых задание БУДЕТ выполнено. Если ни одно из условий не совпало, задание пропускается.exceptопределяет список условий, при которых задание НЕ БУДЕТ выполнено. Он является обратной логикой кonly.
Эти директивы можно применять как к целым заданиям, так и к более крупным структурам, таким как stages. Их использование позволяет избежать ненужных запусков, например, не запускать развертывание в production для каждой ветки или не запускать тяжелые тесты для простых изменений в документации.
Ключевые условия (keywords) для only и except
Наиболее часто используемые ключевые слова:
branches/tags: Фильтрация по имени ветки или тега. Поддерживают простые шаблоны (например,main,feature/*,*-stable).merge_requests: Запуск задания для событий, связанных с Merge/Pull Request (создание, обновление, принятие).api,web,pipelines,triggers,schedules,pushes,chats: Фильтрация по источнику запуска конвейера. Например,only: [schedules]для job, который должен выполняться только по расписанию (ночью).refs: Более общее условие, включающее в себя ветки, теги и Merge Request.variables: Проверка значений переменных CI/CD. Позволяет создавать сложные логические условия.
Примеры использования в .gitlab-ci.yml
Рассмотрим несколько практических сценариев.
1. Запуск тестов только для веток, кроме main и production:
unit_tests:
stage: test
script: ./run_tests.sh
only:
- branches
except:
- main
- production
2. Сборка и публикация Docker-образа только при создании тега (релиз):
build_docker_image:
stage: build
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
only:
- tags
3. Специальное задание для Merge Request (например, предпросмотр окружения):
deploy_review:
stage: deploy
script: ./deploy_to_review.sh
only:
- merge_requests
4. Сложное условие с использованием variables:
security_scan:
stage: security
script: ./run_sonarqube.sh
only:
refs:
- branches
variables:
- $SECURITY_SCAN == "true" || $CI_COMMIT_BRANCH == "main"
Это задание запустится для любых веток, но только если задана переменная SECURITY_SCAN=true ИЛИ если ветка — main.
Эволюция: переход на rules
Важно отметить, что начиная с GitLab 12.3, директивы only и except считаются устаревшими (deprecated), хотя и продолжают работать. Им на смену пришла более мощная и гибкая директива rules.
rules предлагает улучшенный синтаксис, позволяющий комбинировать условия с помощью if, changes, exists, а также явно указывать, что делать при совпадении (when: on_success, when: manual, when: never). Это устраняет некоторые неочевидности логики only/except и дает больше контроля.
Пример эквивалента на rules:
# Старый стиль с only/except
deploy_to_staging:
only:
- main
except:
- tags
# Новый стиль с rules
deploy_to_staging:
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: on_success
- when: never
Вывод
only и except — это исторически важные инструменты GitLab CI для управления потоком выполнения конвейера. Их понимание критически необходимо для работы с существующими проектами. Однако при создании новых конвейеров или рефакторинге старых следует отдавать предпочтение более современной и выразительной директиве rules, которая предоставляет лучшую читаемость, предсказуемость и возможности для создания сложных условий запуска заданий. Это переход от простой фильтрации к декларативному описанию политик выполнения.