Ручная job блокирует pipeline: when manual и allow_failure

Ручной релиз перенесли в rules, и прежде зелёный pipeline стал показывать blocked. Команда ничего не запускала, ошибок в журнале нет. Изменился не только способ отбора job: у when: manual внутри rules другое значение allow_failure по умолчанию. Теперь GitLab ждёт обязательного решения оператора.

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

Две ручные задачи в одном примере

Следующий файл можно использовать в тестовом проекте. Ни одна job не меняет окружение. В основной ветке он показывает необязательную диагностику, обязательное подтверждение и финальную задачу после подтверждения.

stages: [test, approval, finish]
default:
  image: alpine:3.21

tests:
  stage: test
  script: test -n "$CI_COMMIT_SHA"

diagnostics:
  stage: test
  when: manual
  allow_failure: true
  script: uname -s

approve_demo:
  stage: approval
  rules:
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
      when: manual
      allow_failure: false
  script: test -n "$CI_COMMIT_SHA"

finish:
  stage: finish
  script: printf '%s\n' "$CI_COMMIT_SHA"

В main после tests pipeline ожидает approve_demo. Незапущенная diagnostics не мешает этому переходу. Когда оператор запускает approve_demo и она проходит, finish получает управление. В обычной ветке approve_demo отсутствует, поэтому после успешных tests завершается и finish. Эта схема допускает разные наборы jobs, но сохраняет ясную роль каждого ручного действия.

Почему перенос в rules изменил поведение

У manual job вне rules по умолчанию allow_failure: true. Внутри правила с when: manual значение по умолчанию false. Поэтому внешне одинаковая кнопка может быть optional или blocking. В примере оба значения указаны явно, чтобы читатель не восстанавливал их из расположения ключей.

Allow_failure: true влияет и на ошибку уже запущенной job: она не делает весь pipeline неуспешным обычным способом. Для обязательного теста или релиза это может быть неверной политикой. Не исправляйте blocked массовым добавлением true, пока не решили, допустим ли неуспешный результат конкретного действия.

Когда блокировка нужна релизу

Если следующие стадии должны выполняться только после ручной проверки, blocking manual job даёт читаемый барьер. При этом слово approve в имени не устанавливает, кто имеет право нажать кнопку. Для ограничения операторов используйте принятую модель доступа, например protected environments при доступности этой функции в вашей редакции GitLab.

Проверьте также настройки merge request. Если проект требует успешного pipeline перед merge, blocked может удерживать объединение изменений. Возможно, обязательный production-релиз не должен входить в проверочный MR pipeline вообще. Тогда исправляют rules релизной job, сохраняя обязательность там, где она действительно нужна.

Needs может поменять ожидаемый барьер

У job с needs порядок определяется её явными зависимостями. Не рассчитывайте только на расположение manual job в предыдущей stage: потребитель с отдельным графом может обойти ожидаемую последовательность. Посмотрите, на какой результат он должен ждать, и выразите эту зависимость в needs, если используется такой граф.

Если manual job появляется лишь в части pipelines, зависимость потребителя должна учитывать тот же набор условий. Необязательное наличие в графе и необязательный результат — разные вещи. Optional у needs не превращает ошибку существующей блокирующей job в успех.

Проверка должна включать отсутствие нажатия

Запустите пример в main и не нажимайте ничего: pipeline должен ожидать approve_demo. Затем выполните только diagnostics и убедитесь, что ожидание сохраняется. После успешного approve_demo должна исполниться finish. Отдельно проверьте ошибку ручной задачи на безопасном стенде, потому что именно allow_failure определит итог.

Когда смысл кнопки и реакция на её ошибку записаны явно, статус blocked становится объяснимым состоянием процесса. Команда понимает, нужен ли оператор, кто принимает решение и какая следующая задача ожидает этого решения.

Ещё по теме

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

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

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

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

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