Files
code-review-agent/redeploy-ubuntu.sh
Primakov Alexandr Alexandrovich 493a14e2c8 Enhance deployment documentation and add redeploy guide
- Updated `README.md` to include instructions for the new `redeploy-ubuntu.sh` script and added a link to the new `REDEPLOY_GUIDE.md`.
- Created `REDEPLOY_GUIDE.md` detailing the redeployment process, including backup creation, code updates, and troubleshooting steps.
- Introduced `redeploy-hint.md` for GitHub Actions automation example, outlining setup for automatic redeployment on push events.
- Improved documentation structure for better navigation and clarity.
2025-10-13 00:15:47 +03:00

306 lines
11 KiB
Bash

#!/usr/bin/env bash
###############################################################################
# AI Code Review Agent - Redeploy Script для Ubuntu/Debian
###############################################################################
#
# Этот скрипт обновляет и перезапускает AI Review Agent на сервере
#
# Использование:
# sudo bash redeploy-ubuntu.sh
# или
# sudo ./redeploy-ubuntu.sh
#
###############################################################################
# Проверка, что используется bash
if [ -z "$BASH_VERSION" ]; then
echo "ERROR: Этот скрипт требует bash. Запустите: sudo bash redeploy-ubuntu.sh"
exit 1
fi
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
# Определить директорию установки
# Если скрипт запущен из текущей директории, используем её
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INSTALL_DIR="${SCRIPT_DIR}"
SERVICE_NAME="ai-review"
# Проверить, что это похоже на директорию AI Review
if [ ! -d "$INSTALL_DIR/backend" ] || [ ! -d "$INSTALL_DIR/frontend" ]; then
print_error "Не найдены директории backend или frontend"
print_warning "Запустите скрипт из корня проекта AI Review Agent"
exit 1
fi
# Проверка, что сервис установлен
if ! systemctl list-unit-files | grep -q "^${SERVICE_NAME}.service"; then
print_warning "Сервис ${SERVICE_NAME} не найден в systemd"
print_warning "Продолжаем без управления сервисом..."
SERVICE_EXISTS=false
else
SERVICE_EXISTS=true
fi
cd "$INSTALL_DIR"
print_warning "Рабочая директория: $INSTALL_DIR"
# ============================================================================
# Шаг 1: Остановка сервиса
# ============================================================================
print_step 1 7 "Остановка сервиса..."
if [ "$SERVICE_EXISTS" = true ]; then
systemctl stop "$SERVICE_NAME" || print_warning "Не удалось остановить сервис"
print_success "Сервис остановлен"
else
print_warning "Сервис не установлен, пропускаем остановку"
fi
# ============================================================================
# Шаг 2: Создание backup
# ============================================================================
print_step 2 7 "Создание backup..."
BACKUP_DIR="$INSTALL_DIR/backups"
mkdir -p "$BACKUP_DIR" || print_warning "Не удалось создать директорию backup"
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/" 2>/dev/null || {
print_warning "Не удалось создать backup БД"
}
if [ -f "$BACKUP_PATH/review.db" ]; then
print_success "База данных сохранена в $BACKUP_PATH"
fi
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 2>/dev/null || true
fi
# Получить текущую ветку
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
print_warning "Текущая ветка: $CURRENT_BRANCH"
# Обновить код
sudo -u "$REAL_USER" git fetch --all 2>/dev/null || print_warning "Не удалось обновить из git"
sudo -u "$REAL_USER" git pull origin "$CURRENT_BRANCH" 2>/dev/null || print_warning "Не удалось выполнить git pull"
# Восстановить .env
if [ -f "/tmp/ai-review-env-backup" ]; then
cp /tmp/ai-review-env-backup backend/.env 2>/dev/null || true
rm /tmp/ai-review-env-backup 2>/dev/null || true
fi
print_success "Код обновлен"
else
print_warning "Не git репозиторий, пропускаем обновление кода"
print_warning "Предполагается, что код уже обновлен вручную"
sleep 2
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" 2>/dev/null || print_warning "Не удалось установить права"
if [ "$SERVICE_EXISTS" = true ]; then
# Запустить сервис
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
else
print_warning "Сервис не установлен в systemd"
print_warning "Запустите вручную: cd backend && source venv/bin/activate && uvicorn app.main:app --host 0.0.0.0 --port 8000"
fi
# ============================================================================
# Финал
# ============================================================================
echo ""
echo -e "${GREEN}╔════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ Redeploy завершен успешно! ✅ ║${NC}"
echo -e "${GREEN}╚════════════════════════════════════════╝${NC}"
echo ""
# Получить IP адрес
SERVER_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
if [ -z "$SERVER_IP" ]; then
SERVER_IP="localhost"
fi
echo "Сервис: http://${SERVER_IP}:8000"
if [ "$SERVICE_EXISTS" = true ]; then
echo "Статус: systemctl status $SERVICE_NAME"
echo "Логи: journalctl -u $SERVICE_NAME -f"
else
echo "Запуск: cd $INSTALL_DIR/backend && source venv/bin/activate && uvicorn app.main:app --host 0.0.0.0 --port 8000"
fi
echo ""
if [ -f "$BACKUP_PATH/review.db" ]; then
echo "Backup создан: $BACKUP_PATH"
echo ""
echo -e "${YELLOW}Для отката к предыдущей версии:${NC}"
echo " 1. Остановите сервис"
if [ -d ".git" ]; then
echo " 2. Восстановите БД: sudo cp $BACKUP_PATH/review.db $INSTALL_DIR/backend/"
echo " 3. Откатите git: cd $INSTALL_DIR && git reset --hard HEAD~1"
echo " 4. Запустите redeploy снова: cd $INSTALL_DIR && sudo bash redeploy-ubuntu.sh"
else
echo " 2. Восстановите БД: sudo cp $BACKUP_PATH/review.db $INSTALL_DIR/backend/"
echo " 3. Восстановите старые файлы вручную"
fi
fi
echo ""