ci: пересобирать только изменённые сервисы + полный клон для diff
All checks were successful
Deploy / deploy (push) Successful in 3s

Первый прогон вслепую пересобирал все 5 бэкенд-образов, включая worker-gpu
(torch/faiss ~2 ГБ) — на медленном канале это ~1-2 часа впустую, хотя коммит
менял только CI-файлы. Теперь deploy.sh по git-diff с прошлого деплоя
(маркер .last_deploy_sha) собирает лишь сервисы с изменённым кодом; фронт
пересобирается только при правках services/frontend; правка compose = полная
пересборка. Workflow клонирует репозиторий полностью (нужен лог для diff).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jze9
2026-07-29 13:34:30 +05:00
parent 34fa495fb1
commit 8dc51a4f65
2 changed files with 71 additions and 38 deletions

View File

@@ -16,12 +16,12 @@ jobs:
deploy:
runs-on: deploy
steps:
- name: Клонировать текущий коммит
- name: Клонировать репозиторий (полностью — нужен git-лог для diff)
run: |
set -euo pipefail
SRC="$(mktemp -d)"
echo "SRC=$SRC" >> "$GITHUB_ENV"
git clone --depth 1 --branch main \
git clone --branch main \
https://gitea.jze9.ru/jze9/anti-plagiarism.git "$SRC"
- name: Деплой (бэкенд 1.32 + фронтенд CT 102)

View File

@@ -1,28 +1,55 @@
#!/usr/bin/env bash
# ─────────────────────────────────────────────────────────────────────────────
# Деплой anti-plagiarism.
# Деплой anti-plagiarism (умная пересборка — только изменённых сервисов).
#
# Запускается Gitea Actions runner'ом в host-режиме прямо на app-хосте 1.32
# (см. .gitea/workflows/deploy.yml). Ожидает:
# - cwd = свежий чекаут репозитория;
# - переменную окружения PVE_PASSWORD (секрет Gitea) для доступа к Proxmox-хосту,
# через который статика кладётся в CT 102 (reverse-proxy nginx).
# - cwd = ПОЛНЫЙ чекаут репозитория (нужен git-лог для diff);
# - переменную PVE_PASSWORD (секрет) для доступа к Proxmox-хосту → CT 102.
#
# Что делает:
# 1. Синхронизирует код (services/ + scripts/) в /home/user/anti-plagiarism,
# НЕ трогая .env и локально-правленый docker-compose.prod.yml.
# 2. Пересобирает и перезапускает бэкенд-сервисы (api + воркеры).
# 3. Применяет миграции БД.
# 4. Собирает фронтенд (npm build) в статику.
# 5. Выкладывает статику в /var/www/academic на CT 102 (с бэкапом + reload nginx).
# Пересобирается только то, чей код изменился с прошлого деплоя (маркер SHA в
# $APP/.last_deploy_sha). Это критично: worker-gpu тянет torch/faiss (~2 ГБ),
# его нельзя пересобирать без нужды. Если менялся docker-compose.prod.yml
# пересобираются все бэкенд-сервисы.
# ─────────────────────────────────────────────────────────────────────────────
set -euo pipefail
APP=/home/user/anti-plagiarism
SRC="$(pwd)"
PVE_HOST=192.168.20.254 # Proxmox-хост, через pct exec которого живёт CT 102
PVE_HOST=192.168.20.254
COMPOSE="docker compose -f docker-compose.prod.yml"
BACKEND_SERVICES="api worker-gpu worker-indexer worker-notifier worker-gost"
ALL_BACKEND="api worker-gpu worker-indexer worker-notifier worker-gost"
MARKER="$APP/.last_deploy_sha"
CUR_SHA="$(git -C "$SRC" rev-parse HEAD)"
# ── Определить, что менялось ──────────────────────────────────────────────────
FULL=0
CHANGED=""
if [ -f "$MARKER" ] && PREV="$(cat "$MARKER")" && [ -n "$PREV" ] \
&& git -C "$SRC" cat-file -e "$PREV" 2>/dev/null; then
CHANGED="$(git -C "$SRC" diff --name-only "$PREV" "$CUR_SHA")"
echo "Изменения с $PREV:"
echo "$CHANGED" | sed 's/^/ /'
# Правка общего compose затрагивает все образы
echo "$CHANGED" | grep -qE '^docker-compose\.prod\.yml$' && FULL=1
else
echo "Маркер прошлого деплоя недоступен — полная пересборка (разовая)"
FULL=1
fi
REBUILD=""
FRONTEND_CHANGED=0
if [ "$FULL" = 1 ]; then
REBUILD="$ALL_BACKEND"
FRONTEND_CHANGED=1
else
for svc in $ALL_BACKEND; do
echo "$CHANGED" | grep -qE "^services/$svc/" && REBUILD="$REBUILD $svc"
done
echo "$CHANGED" | grep -qE '^services/frontend/' && FRONTEND_CHANGED=1
fi
REBUILD="$(echo "$REBUILD" | xargs || true)"
echo "==> [1/5] Синхронизация кода в $APP (сохраняя .env и compose)"
rsync -a \
@@ -30,20 +57,22 @@ rsync -a \
--exclude='node_modules/' --exclude='dist/' \
"$SRC/services" "$SRC/scripts" "$APP/"
echo "==> [2/5] Пересборка и перезапуск бэкенд-сервисов"
cd "$APP"
if [ -n "$REBUILD" ]; then
echo "==> [2/5] Пересборка и перезапуск: $REBUILD"
# shellcheck disable=SC2086
$COMPOSE up -d --build $BACKEND_SERVICES
echo "==> [3/5] Миграции БД (с ретраем, пока api поднимается)"
for i in $(seq 1 10); do
if $COMPOSE exec -T api alembic upgrade head; then
break
$COMPOSE up -d --build $REBUILD
else
echo "==> [2/5] Бэкенд-сервисы не менялись — пропуск сборки"
fi
echo " api ещё не готов, повтор $i/10..."
sleep 5
echo "==> [3/5] Миграции БД (с ретраем)"
for i in $(seq 1 10); do
$COMPOSE exec -T api alembic upgrade head && break
echo " api ещё не готов, повтор $i/10..."; sleep 5
done
if [ "$FRONTEND_CHANGED" = 1 ]; then
echo "==> [4/5] Сборка фронтенда"
docker run --rm -v "$APP/services/frontend":/app -w /app node:20-slim \
sh -c "npm install --no-audit --no-fund --loglevel=error && npm run build"
@@ -72,5 +101,9 @@ nginx -t && nginx -s reload
rm -f /tmp/academic-dist.tgz
REMOTE
rm -f /tmp/academic-dist.tgz
else
echo "==> [4-5/5] Фронтенд не менялся — пропуск сборки и выкладки"
fi
echo "==> Деплой завершён успешно"
echo "$CUR_SHA" > "$MARKER"
echo "==> Деплой завершён успешно (маркер обновлён: $CUR_SHA)"