Как определить в гитлаб запуск джобы по кнопке?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Определение ручного запуска джобы в 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. Это обеспечивает гибкость и соответствие требованиям вашего процесса доставки.