#!/bin/bash ############################################################################### # AI Code Review Agent - Redeploy Script для Ubuntu/Debian ############################################################################### # # Этот скрипт обновляет и перезапускает AI Review Agent на сервере # # Использование: # sudo ./redeploy-ubuntu.sh # ############################################################################### set -e # Выход при ошибке # Цвета для вывода RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Функции для красивого вывода print_step() { echo -e "\n${BLUE}[STEP $1/$2]${NC} $3" } print_success() { echo -e "${GREEN}[OK]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_header() { echo -e "\n${GREEN}╔════════════════════════════════════════╗${NC}" echo -e "${GREEN}║ AI Review Agent - Redeploy ║${NC}" echo -e "${GREEN}╚════════════════════════════════════════╝${NC}\n" } # Проверка прав root if [ "$EUID" -ne 0 ]; then print_error "Запустите скрипт с sudo" exit 1 fi print_header # Определить пользователя, который запустил sudo REAL_USER="${SUDO_USER:-$USER}" if [ "$REAL_USER" = "root" ]; then print_error "Не запускайте этот скрипт напрямую из-под root. Используйте sudo от обычного пользователя." exit 1 fi INSTALL_DIR="/opt/ai-review" SERVICE_NAME="ai-review" # Проверка, что сервис установлен if [ ! -d "$INSTALL_DIR" ]; then print_error "AI Review Agent не установлен в $INSTALL_DIR" print_warning "Сначала запустите deploy-ubuntu.sh" exit 1 fi if ! systemctl list-unit-files | grep -q "^${SERVICE_NAME}.service"; then print_error "Сервис ${SERVICE_NAME} не найден" print_warning "Сначала запустите deploy-ubuntu.sh" exit 1 fi cd "$INSTALL_DIR" # ============================================================================ # Шаг 1: Остановка сервиса # ============================================================================ print_step 1 7 "Остановка сервиса..." systemctl stop "$SERVICE_NAME" print_success "Сервис остановлен" # ============================================================================ # Шаг 2: Создание backup # ============================================================================ print_step 2 7 "Создание backup..." BACKUP_DIR="/opt/ai-review-backups" mkdir -p "$BACKUP_DIR" BACKUP_NAME="backup-$(date +%Y%m%d-%H%M%S)" BACKUP_PATH="$BACKUP_DIR/$BACKUP_NAME" # Backup базы данных if [ -f "$INSTALL_DIR/backend/review.db" ]; then mkdir -p "$BACKUP_PATH" cp "$INSTALL_DIR/backend/review.db" "$BACKUP_PATH/" print_success "База данных сохранена в $BACKUP_PATH" else print_warning "База данных не найдена, пропускаем backup" fi # ============================================================================ # Шаг 3: Обновление кода # ============================================================================ print_step 3 7 "Обновление кода..." # Проверка, что это git репозиторий if [ -d ".git" ]; then # Сохранить изменения в .env если есть if [ -f "backend/.env" ]; then cp backend/.env /tmp/ai-review-env-backup fi # Получить текущую ветку CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) print_warning "Текущая ветка: $CURRENT_BRANCH" # Обновить код sudo -u "$REAL_USER" git fetch --all sudo -u "$REAL_USER" git pull origin "$CURRENT_BRANCH" # Восстановить .env if [ -f "/tmp/ai-review-env-backup" ]; then cp /tmp/ai-review-env-backup backend/.env rm /tmp/ai-review-env-backup fi print_success "Код обновлен" else print_warning "Не git репозиторий, пропускаем обновление кода" echo "Если вы хотите обновить код вручную, сделайте это сейчас" read -p "Продолжить? (y/n): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then print_error "Отменено" systemctl start "$SERVICE_NAME" exit 1 fi fi # ============================================================================ # Шаг 4: Обновление зависимостей Backend # ============================================================================ print_step 4 7 "Обновление зависимостей Backend..." cd backend # Активировать venv и установить зависимости if [ -d "venv" ]; then sudo -u "$REAL_USER" bash -c " source venv/bin/activate pip install --upgrade pip > /dev/null 2>&1 pip install -r requirements.txt > /dev/null 2>&1 " print_success "Зависимости Backend обновлены" else print_error "Virtual environment не найден" exit 1 fi # ============================================================================ # Шаг 5: Применение миграций БД # ============================================================================ print_step 5 7 "Применение миграций БД..." if [ -f "migrate.py" ]; then sudo -u "$REAL_USER" bash -c " source venv/bin/activate python migrate.py " 2>&1 | grep -E "(✅|Таблицы|создан)" || true print_success "Миграции применены" else print_warning "Скрипт миграции не найден, пропускаем" fi cd .. # ============================================================================ # Шаг 6: Сборка Frontend # ============================================================================ print_step 6 7 "Сборка Frontend..." cd frontend # Проверить наличие Node.js if ! command -v node &> /dev/null; then print_error "Node.js не установлен" exit 1 fi # Установить зависимости если нужно if [ ! -d "node_modules" ]; then print_warning "Установка зависимостей..." sudo -u "$REAL_USER" npm install > /dev/null 2>&1 fi # Создать .env.production для правильных URL cat > .env.production << EOF VITE_API_URL=/api VITE_WS_URL= EOF # Собрать frontend sudo -u "$REAL_USER" npm run build 2>&1 | grep -E "(✓|built in)" || true print_success "Frontend собран" # Проверить, что build создан if [ ! -d "../backend/public" ]; then print_error "Frontend не собрался в backend/public" exit 1 fi cd .. # ============================================================================ # Шаг 7: Запуск сервиса # ============================================================================ print_step 7 7 "Запуск сервиса..." # Установить правильные права chown -R "$REAL_USER:$REAL_USER" "$INSTALL_DIR" # Запустить сервис systemctl start "$SERVICE_NAME" # Подождать немного sleep 2 # Проверить статус if systemctl is-active --quiet "$SERVICE_NAME"; then print_success "Сервис запущен" else print_error "Сервис не запустился" echo "" echo "Логи сервиса:" journalctl -u "$SERVICE_NAME" -n 20 --no-pager exit 1 fi # ============================================================================ # Финал # ============================================================================ echo "" echo -e "${GREEN}╔════════════════════════════════════════╗${NC}" echo -e "${GREEN}║ Redeploy завершен успешно! ✅ ║${NC}" echo -e "${GREEN}╚════════════════════════════════════════╝${NC}" echo "" echo "Сервис: http://$(hostname -I | awk '{print $1}'):8000" echo "Статус: systemctl status $SERVICE_NAME" echo "Логи: journalctl -u $SERVICE_NAME -f" echo "" echo "Backup создан: $BACKUP_PATH" echo "" echo -e "${YELLOW}Для отката к предыдущей версии:${NC}" echo " 1. Остановите сервис: sudo systemctl stop $SERVICE_NAME" echo " 2. Восстановите БД: sudo cp $BACKUP_PATH/review.db $INSTALL_DIR/backend/" echo " 3. Откатите git: cd $INSTALL_DIR && sudo -u $REAL_USER git reset --hard HEAD~1" echo " 4. Запустите redeploy снова: sudo ./redeploy-ubuntu.sh" echo ""