name: CI & CD pipeline on: push: branches: [ main, 'develop', 'dev-*', 'feature/**' ] pull_request: branches: [ main, develop ] jobs: test: runs-on: ubuntu-latest name: Test steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python 3.11 uses: actions/setup-python@v5 with: python-version: '3.11' cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r tests/infra/requirements-test.txt - name: Run infrastructure tests run: | python -m pytest tests/infra/ -v --tb=short - name: Validate Prometheus config run: | python -m pytest tests/infra/test_prometheus_config.py -v - name: Upload test results if: always() uses: actions/upload-artifact@v4 with: name: test-results path: | .pytest_cache/ htmlcov/ retention-days: 7 - name: Send test results notification if: always() uses: appleboy/telegram-action@v1.0.0 with: to: ${{ secrets.TELEGRAM_CHAT_ID }} token: ${{ secrets.TELEGRAM_BOT_TOKEN }} message: | 🧪 CI Tests ${{ job.status }} Repository: prod Branch: ${{ github.ref_name }} Commit: ${{ github.sha }} Author: ${{ github.actor }} ${{ job.status == 'success' && '✅ All tests passed! Ready for deployment.' || '❌ Tests failed! Deployment blocked.' }} View details: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} continue-on-error: true deploy: runs-on: ubuntu-latest name: Deploy needs: test if: success() && github.ref == 'refs/heads/main' environment: name: production steps: - name: Checkout code uses: actions/checkout@v4 - name: Deploy to server uses: appleboy/ssh-action@v1.0.0 with: host: ${{ vars.SERVER_HOST || secrets.SERVER_HOST }} username: ${{ vars.SERVER_USER || secrets.SERVER_USER }} key: ${{ secrets.SSH_PRIVATE_KEY }} port: ${{ vars.SSH_PORT || secrets.SSH_PORT || 22 }} script: | set -e echo "🚀 Starting deployment..." # Переходим в директорию проекта cd /home/prod # Сохраняем текущий коммит для отката CURRENT_COMMIT=$(git rev-parse HEAD) echo "Current commit: $CURRENT_COMMIT" > /tmp/last_deploy_commit.txt # Обновляем код echo "📥 Pulling latest changes..." # Исправляем права на файлы перед обновлением sudo chown -R deploy:deploy /home/prod || true git fetch origin main git reset --hard origin/main # Устанавливаем правильные права после обновления sudo chown -R deploy:deploy /home/prod || true # Проверяем, что изменения есть NEW_COMMIT=$(git rev-parse HEAD) if [ "$CURRENT_COMMIT" = "$NEW_COMMIT" ]; then echo "ℹ️ No new changes to deploy" else echo "✅ Code updated: $CURRENT_COMMIT → $NEW_COMMIT" fi # Перезапускаем сервисы echo "🔄 Restarting services..." if command -v make &> /dev/null; then make restart || docker-compose restart else cd /home/prod docker-compose down docker-compose up -d --build fi echo "✅ Deployment completed" - name: Health check uses: appleboy/ssh-action@v1.0.0 with: host: ${{ vars.SERVER_HOST || secrets.SERVER_HOST }} username: ${{ vars.SERVER_USER || secrets.SERVER_USER }} key: ${{ secrets.SSH_PRIVATE_KEY }} port: ${{ vars.SSH_PORT || secrets.SSH_PORT || 22 }} script: | echo "🏥 Running health checks..." sleep 15 # Даем время сервисам запуститься # Проверяем Prometheus if curl -f http://localhost:9090/-/healthy > /dev/null 2>&1; then echo "✅ Prometheus is healthy" else echo "❌ Prometheus health check failed" exit 1 fi # Проверяем Grafana if curl -f http://localhost:3000/api/health > /dev/null 2>&1; then echo "✅ Grafana is healthy" else echo "❌ Grafana health check failed" exit 1 fi # Проверяем статус контейнеров echo "📊 Container status:" cd /home/prod docker-compose ps || docker ps --filter "name=bots_" echo "✅ All health checks passed" - name: Send deployment notification if: always() uses: appleboy/telegram-action@v1.0.0 with: to: ${{ secrets.TELEGRAM_CHAT_ID }} token: ${{ secrets.TELEGRAM_BOT_TOKEN }} message: | 🚀 Deployment ${{ job.status }} Repository: prod Branch: ${{ github.ref_name }} Commit: ${{ github.sha }} Author: ${{ github.actor }} ${{ job.status == 'success' && '✅ Deployment successful!' || '❌ Deployment failed!' }} View details: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} continue-on-error: true