name: Deploy to Production on: workflow_dispatch: # Только ручной запуск jobs: check-ci-status: runs-on: ubuntu-latest name: Check CI Status steps: - name: Checkout code uses: actions/checkout@v4 - name: Check last CI run status uses: actions/github-script@v7 with: script: | const { data: runs } = await github.rest.actions.listWorkflowRuns({ owner: context.repo.owner, repo: context.repo.repo, workflow_id: 'ci.yml', branch: 'main', per_page: 1 }); if (runs.workflow_runs.length === 0) { core.setFailed('❌ No CI runs found. Please run CI first.'); return; } const lastRun = runs.workflow_runs[0]; const status = lastRun.status; const conclusion = lastRun.conclusion; console.log(`Last CI run: ${lastRun.id}`); console.log(`Status: ${status}, Conclusion: ${conclusion}`); if (status !== 'completed') { core.setFailed(`❌ Last CI run is still ${status}. Please wait for it to complete.`); return; } if (conclusion !== 'success') { core.setFailed(`❌ Last CI run failed (${conclusion}). Please fix tests before deploying.`); return; } console.log('✅ Last CI run passed successfully. Ready for deployment!'); deploy: runs-on: ubuntu-latest name: Deploy Infrastructure needs: check-ci-status 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