16 KiB
🚀 Документация CI/CD Pipeline NOCR
📋 Обзор
Проект NOCR использует современную многопайплайновую CI/CD систему на базе Drone CI, работающую на Kubernetes. Этот документ описывает 5 специализированных пайплайнов и способы их использования.
🎯 Архитектура пайплайнов
Пайплайн 1: Feature Validation (Валидация функциональных веток)
Триггер: Push в ветки feature/*, fix/* или issues/*
Назначение: Быстрая обратная связь для разработчиков
Длительность: ~3-5 минут
Что делает:
- Клонирует репозиторий с субмодулями
- Восстанавливает все NuGet-пакеты (общий кэш)
- Собирает все 4 сервиса в Debug-режиме
- Запускает unit и integration тесты с Testcontainers
Пример рабочего процесса:
git checkout -b feature/add-new-filter
# Внесите изменения...
git add .
git commit -m "Add new filter functionality"
git push origin feature/add-new-filter
Drone автоматически запустит тесты. Проверьте результаты перед созданием PR.
Пайплайн 2: Main Validation (Валидация основной ветки)
Триггер: Push в ветку main
Назначение: Валидация основной ветки после мерджа
Длительность: ~3-5 минут
Что делает:
- То же, что и Feature Validation
- Гарантирует, что ветка main всегда в рабочем состоянии
Пример рабочего процесса:
# После мерджа PR в main
# Пайплайн запускается автоматически
Пайплайн 3: Contracts-Only Publish (Публикация только контрактов)
Триггер: Тег с сообщением коммита, содержащим contracts_only:<service>
Назначение: Быстрая публикация NuGet-пакетов контрактов без сборки Docker-образов
Длительность: ~2 минуты
Что делает:
- Упаковывает контракты указанного сервиса в NuGet-пакеты
- Публикует во внутреннем NuGet-фиде
- Пропускает сборку Docker-образов
Пример рабочего процесса:
# Обновите контракты telegram-listener
cd telegram-listener
# Внесите изменения в Async.Api.Contracts...
git add .
git commit -m "contracts_only:telegram_listener - Add MessageEdited event"
git push origin main
# Создайте тег
git tag v1.2.4-contracts
git push origin v1.2.4-contracts
Поддерживаемые маркеры:
contracts_only:telegram_listenercontracts_only:text_matchercontracts_only:users
Пайплайн 4: Full Release (Полный релиз)
Триггер: Тег на main БЕЗ contracts_only или deploy_only в сообщении коммита
Назначение: Полный цикл релиза
Длительность: ~8-10 минут
Что делает:
- Этап 1: Публикация всех контрактов в NuGet (параллельно)
- Этап 2: Сборка всех Docker-образов с Kaniko (3 параллельных потока)
- Этап 3: Деплой в Kubernetes (только для тегов, начинающихся с
v)
Пример рабочего процесса:
# Готовы к релизу
git tag v1.3.0
git push origin v1.3.0
# Drone выполнит:
# 1. Публикацию контрактов
# 2. Сборку образов (с тегами v1.3.0, commit SHA, и latest)
# 3. Деплой в k8s (если тег начинается с 'v')
Создаваемые теги образов:
hub.musk.fun/k8s/nocr/telegram_listener:v1.3.0hub.musk.fun/k8s/nocr/telegram_listener:abc1234(commit SHA)hub.musk.fun/k8s/nocr/telegram_listener:latest
Пайплайн 5: Deploy-Only (Только деплой)
Триггер: Тег с сообщением коммита, содержащим deploy_only: <version>
Назначение: Быстрый деплой уже собранных образов
Длительность: ~1 минута
Что делает:
- Пропускает сборку
- Деплоит указанные образы в Kubernetes
- Полезно для отката или продвижения существующих образов
ВАЖНО: В сообщении коммита нужно указать версию образов для деплоя:
Пример рабочего процесса:
# Деплой существующих образов v1.2.9
git commit --allow-empty -m "deploy_only: v1.2.9"
git tag deploy-v1.2.9
git push origin deploy-v1.2.9
# Откат на предыдущую версию v1.2.8
git commit --allow-empty -m "deploy_only: v1.2.8"
git tag rollback-v1.2.8
git push origin rollback-v1.2.8
Формат commit message:
deploy_only: v1.2.9- деплоит образы с тегомv1.2.9- Скрипт извлекает версию из сообщения и использует соответствующие образы
- Образы должны существовать в registry (собраны ранее через full-release)
🛠️ Скрипты деплоя
Все скрипты деплоя находятся в _deploy/scripts/:
deploy.sh
Назначение: Деплой сервисов в Kubernetes Использование:
# Full release (использует TAG для образов)
./deploy.sh v1.3.0 abc1234
# Deploy only (переопределяет тег образа)
./deploy.sh deploy-v1.2.9 def5678 v1.2.9
Параметры:
tag- Git тег (обязательный)commit-sha- SHA коммита (опциональный)image-tag-override- Переопределение тега образа (опциональный, для deploy_only)
Возможности:
- Обновляет deployment-манифесты новыми тегами образов
- Применяет манифесты в кластер
- Ожидает завершения rollout с таймаутом
- Запускает проверки здоровья после деплоя
- Показывает статус подов
rollback.sh
Назначение: Откат деплоев к предыдущей версии Использование:
# Откат одного сервиса
./rollback.sh telegram-listener
# Откат всех сервисов
./rollback.sh all
Возможности:
- Показывает историю ревизий
- Выполняет kubectl rollout undo
- Ожидает завершения отката
- Запускает проверки здоровья после отката
health-check.sh
Назначение: Проверка здоровья всех сервисов NOCR Использование:
./health-check.sh
Проверяет:
- Статус подов (Running/Ready)
- Health-эндпоинты (/health)
- Последние события для упавших подов
📦 Оптимизации
Общий NuGet-кэш
Все пайплайны используют общий временный volume для NuGet-пакетов:
- Первый
dotnet restoreскачивает пакеты - Последующие сборки переиспользуют кэшированные пакеты
- ~60% быстрее, чем индивидуальное восстановление для каждого сервиса
Параллельное выполнение
- Публикация контрактов: 3 сервиса параллельно
- Сборка Docker: 3 параллельных потока
- Независимые операции никогда не блокируют друг друга
Кэширование Kaniko
Все сборки Kaniko используют:
--cache=true- Включено кэширование слоев--cache-repo=hub.musk.fun/k8s/cache/*- Общий репозиторий кэша--compressed-caching=true- Быстрая передача кэша
🧪 Поддержка Testcontainers
Пайплайны валидации Feature и Main включают Docker-in-Docker сервис для Testcontainers:
services:
- name: docker
image: docker:27-dind
privileged: true
Тесты могут использовать Testcontainers для запуска реальных баз данных, очередей сообщений и т.д.
🔒 Необходимые секреты
Настройте эти секреты в Drone:
hub_username- Имя пользователя Docker registryhub_password- Пароль Docker registrynuget_musk_api_key- API-ключ NuGet-фида
📊 Дерево решений пайплайна
Push в feature/* → Feature Validation (сборка + тесты)
Push в main → Main Validation (сборка + тесты)
Тег + "contracts_only:" → Contracts Publish
Тег + "deploy_only:" → Deploy Only
Тег (без маркеров) → Full Release (контракты → образы → деплой)
🎓 Лучшие практики
-
Функциональные ветки
- Всегда создавайте функциональные ветки для новой работы
- Дайте CI валидировать перед мерджем в main
-
Изменения контрактов
- Используйте
contracts_only:для быстрого обновления контрактов - Другие сервисы могут сразу обновить ссылки
- Используйте
-
Процесс релиза
- Создавайте теги только из ветки main
- Используйте семантическое версионирование (v1.2.3)
- Теги, начинающиеся с
v, автоматически деплоятся в k8s
-
Экстренный откат
# Быстрый откат через deploy-only git commit --allow-empty -m "deploy_only: v1.2.8" git tag rollback-v1.2.8 git push origin rollback-v1.2.8 # Или используйте скрипт отката напрямую в кластере kubectl exec -it deploy-pod -- bash cd /flea/_deploy/scripts ./rollback.sh all -
Мониторинг деплоев
- Следите за UI Drone для прогресса пайплайна
- Проверяйте логи подов:
kubectl logs -f deployment/telegram-listener -n nocr - Запускайте проверки здоровья:
./_deploy/scripts/health-check.sh
🐛 Устранение неполадок
Пайплайн завис на "Waiting for contracts"
Причина: Публикация контракта упала Решение: Проверьте NuGet-фид, проверьте API-ключ
Сборка Docker падает с ошибкой "unauthorized"
Причина: Неверные учетные данные registry
Решение: Обновите секреты hub_username и hub_password
Тесты падают с ошибкой "Cannot connect to Docker daemon"
Причина: Testcontainers не может достичь Docker-in-Docker сервиса
Решение: Проверьте, что переменная окружения DOCKER_HOST установлена правильно
Деплой падает с ошибкой "ImagePullBackOff"
Причина: Образ не найден в registry Решение: Проверьте, что образ был собран и запушен успешно на предыдущем этапе
YAML-ошибки в .drone.yml
Причина: Неправильное форматирование многострочных команд или двоеточие в переменных Решение:
- Используйте блоки
|для многострочных команд - Экранируйте переменные с двоеточиями (например,
"${VAR:0:7}") - Проверьте YAML:
python3 -c "import yaml; list(yaml.safe_load_all(open('.drone.yml')))"
📚 Дополнительные ресурсы
🔄 История изменений (15-16 октября 2025)
Исправлена критическая проблема с YAML
Проблема:
- Ошибка
yaml: line 126: mapping values are not allowed in this context - Многострочные команды
/kaniko/executorсодержали переменные с двоеточием (${DRONE_COMMIT_SHA:0:7}) - YAML парсер интерпретировал двоеточие как разделитель ключ:значение
Решение:
- Обернули все команды
/kaniko/executorв многострочные блоки с| - Добавили обратные слэши
\для продолжения команды - Экранировали аргументы с двоеточиями в кавычках
Пример:
# До (неправильно):
commands:
- /kaniko/executor
--destination=hub.musk.fun/image:${DRONE_COMMIT_SHA:0:7}
# После (правильно):
commands:
- |
/kaniko/executor \
--destination=hub.musk.fun/image:${DRONE_COMMIT_SHA:0:7}
Добавлены новые функции
- ✨ Контракты-только пайплайн для быстрой итерации
- 🚀 Деплой-только пайплайн для откатов
- 🔄 Обработка MessageEdited событий
- 📝 Скрипт автокоммита субмодулей
- ⚡ Оптимизированный общий NuGet-кэш
- 🔧 Параллельная сборка и деплой
📞 Поддержка
Если у вас возникли проблемы с CI/CD:
- Проверьте логи в Drone UI: https://drone.musk.fun/nocr/flea
- Проверьте статус подов:
kubectl get pods -n nocr - Запустите health-check:
./health-check.sh - Проверьте логи контейнеров:
kubectl logs -f <pod-name> -n nocr
Для вопросов по инфраструктуре обращайтесь к DevOps-команде.