Что такое only и except в GitLab CI/CD?

«Что такое only и except в GitLab CI/CD?» — вопрос из категории CI/CD, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

only и except — это устаревшие, но все еще встречающиеся директивы в файле .gitlab-ci.yml, которые определяют условия выполнения job (задачи) в пайплайне.

  • only: Определяет, когда job ДОЛЖНА запускаться (белый список условий).
  • except: Определяет, когда job НЕ ДОЛЖНА запускаться (черный список условий).

Пример из практики:

stages:
  - test
  - deploy

unit_tests:
  stage: test
  script: ./run-tests.sh
  only:
    - merge_requests  # Запускать только для MR
    - main            # и для коммитов в main

deploy_to_staging:
  stage: deploy
  script: ./deploy-staging.sh
  only:
    - main            # Деплой на staging только из main
  except:
    - tags            # Но не запускать, если это тег

Почему only/except считается устаревшим и что использовать вместо них?

GitLab рекомендует использовать более гибкую и мощную директиву rules. Она позволяет комбинировать условия с помощью if, changes, exists и явно указывать, что делать при совпадении (when).

Тот же пример, переписанный на rules:

deploy_to_staging:
  stage: deploy
  script: ./deploy-staging.sh
  rules:
    - if: $CI_COMMIT_BRANCH == "main"       # Если ветка main
      when: manual                           # Запускать вручную
    - if: $CI_COMMIT_TAG                     # Если это тег — не запускать
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" # Для MR — запускать автоматически
      when: on_success

Ключевое отличие rules: Позволяет задавать сложную логику (например, "запускать для MR, но только если изменились файлы в папке src/") и явно управлять поведением (when: delayed, when: manual). Для новых проектов следует использовать именно rules.