← Назад к вопросам

Как определить в гитлаб запуск джобы по кнопке?

1.3 Junior🔥 191 комментариев
#CI/CD и автоматизация

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Определение ручного запуска джобы в GitLab CI/CD

В GitLab CI/CD существует два основных подхода для определения, была ли джоба запущена вручную через кнопку (manual execution), а не автоматически пайплайном. Вот основные методы, которые я использую в своей практике.

1. Использование предопределённой переменной CI_JOB_MANUAL

Самым прямым и рекомендуемым способом является проверка значения встроенной переменной окружения CI_JOB_MANUAL. GitLab автоматически устанавливает её в true для всех джоб, запущенных вручную (даже для тех, что имеют when: manual в конфигурации). Эта переменная доступна в контексте скрипта джобы.

Пример конфигурации в .gitlab-ci.yml:

deploy_to_production:
  stage: deploy
  script:
    # Проверяем, запущен ли job вручную
    - |
      if [ "$CI_JOB_MANUAL" == "true" ]; then
        echo "Job запущен вручную через кнопку"
        # Добавляем дополнительную логику, например, интерактивное подтверждение
        ./manual_deployment_checks.sh
      else
        echo "Автоматический запуск джобы"
        ./standard_deployment.sh
      fi
  when: manual # Джоба изначально настроена как ручная
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

Важный нюанс: Переменная CI_JOB_MANUAL будет true для ЛЮБОЙ джобы, запущенной вручную, даже если в её определении нет when: manual. Это ключевое отличие от следующего метода.

2. Анализ переменной CI_PIPELINE_SOURCE и типа пайплайна

Иногда требуется более детальная диагностика. Можно комбинировать проверки, анализируя источник пайплайна. Ручные запуски часто связаны с пайплайнами, источником которых является web (интерфейс GitLab) или schedule (если речь о ручном запуске планировщика).

Пример комплексной проверки:

script:
  - |
    echo "Источник пайплайна: $CI_PIPELINE_SOURCE"
    echo "Запущен вручную (CI_JOB_MANUAL): $CI_JOB_MANUAL"

    if [ "$CI_PIPELINE_SOURCE" == "web" ] && [ "$CI_JOB_MANUAL" == "true" ]; then
      echo "Запуск через кнопку в веб-интерфейсе GitLab."
    elif [ "$CI_PIPELINE_SOURCE" == "schedule" ]; then
      echo "Запуск по расписанию (также может быть инициирован вручную)."
    elif [ "$CI_PIPELINE_SOURCE" == "push" ]; then
      echo "Автоматический запуск по push/мержу."
    fi

3. Использование правил (rules) с переменной $CI_JOB_MANUAL

Для более элегантного разделения логики можно использовать директиву rules:, чтобы создавать разные "пути выполнения" джобы в зависимости от способа запуска.

Пример разделения логики через rules::

deploy:
  stage: deploy
  script:
    - echo "Стандартный деплой"
  rules:
    # Правило для автоматического запуска при мерже в main
    - if: $CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push"
      when: always

    # Правило для ручного запуска с дополнительными шагами
    - if: $CI_JOB_MANUAL == "true"
      when: manual
      script:
        - echo "Деплой с ручным подтверждением"
        - ./extended_manual_verification.sh
        - echo "Основной скрипт деплоя"

4. Проверка через GitLab API (продвинутый способ)

В редких случаях, когда контекста переменных недостаточно, можно запросить информацию о конкретном пайплайне или джобе через GitLab REST API. Это полезно для скриптов, работающих вне контекста Runner'а, или для интеграций.

Пример скрипта на Python, проверяющего тип запуска:

#!/usr/bin/env python3
import os
import requests

GITLAB_URL = os.getenv('CI_SERVER_URL', 'https://gitlab.com')
PROJECT_ID = os.getenv('CI_PROJECT_ID')
JOB_ID = os.getenv('CI_JOB_ID')
PRIVATE_TOKEN = os.getenv('GITLAB_PRIVATE_TOKEN') # Токен должен быть предварительно задан

api_url = f"{GITLAB_URL}/api/v4/projects/{PROJECT_ID}/jobs/{JOB_ID}"
headers = {"PRIVATE-TOKEN": PRIVATE_TOKEN}

response = requests.get(api_url, headers=headers)
job_data = response.json()

if job_data.get('status') == 'manual':
    print("Джоба была запущена вручную (на основе статуса из API).")
if job_data.get('pipeline', {}).get('source') == 'web':
    print("Пайплайн запущен через веб-интерфейс.")

5. Практические рекомендации и нюансы

  • when: delayed: Джобы с задержкой (when: delayed) также считаются ручными для системы, и для них CI_JOB_MANUAL будет true.
  • Запуск через API: Если джоба запускается через вызов GitLab API (например, POST /projects/:id/pipeline), переменная CI_PIPELINE_SOURCE примет значение api, а CI_JOB_MANUAL будет false, если в запросе не указано иное. Это важно для автоматизации внешними системами.
  • Безопасность: Не стоит полагаться ТОЛЬКО на факт ручного запуска для пропуска критических проверок безопасности. Всегда комбинируйте его с другими правилами (например, проверкой ветки, тега или наличия определённой метки).
  • Логирование: Для аудита добавьте логирование способа запуска в самом начале скрипта:
    echo "--- Контекст выполнения ---"
    echo "Job ID: $CI_JOB_ID"
    echo "Job Name: $CI_JOB_NAME"
    echo "Pipeline Source: $CI_PIPELINE_SOURCE"
    echo "Manual Job: $CI_JOB_MANUAL"
    echo "--- Конец контекста ---"
    

Итог: Для простого и надежного определения ручного запуска по кнопке используйте проверку переменной if [ "$CI_JOB_MANUAL" == "true" ] внутри скрипта. Для более сложных сценариев, таких как разное поведение или разделение этапов в rules, комбинируйте её с CI_PIPELINE_SOURCE и другими переменными GitLab CI. Это обеспечивает гибкость и соответствие требованиям вашего процесса доставки.