ci: пересобирать только изменённые сервисы + полный клон для diff
All checks were successful
Deploy / deploy (push) Successful in 3s
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:
@@ -16,12 +16,12 @@ jobs:
|
|||||||
deploy:
|
deploy:
|
||||||
runs-on: deploy
|
runs-on: deploy
|
||||||
steps:
|
steps:
|
||||||
- name: Клонировать текущий коммит
|
- name: Клонировать репозиторий (полностью — нужен git-лог для diff)
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
SRC="$(mktemp -d)"
|
SRC="$(mktemp -d)"
|
||||||
echo "SRC=$SRC" >> "$GITHUB_ENV"
|
echo "SRC=$SRC" >> "$GITHUB_ENV"
|
||||||
git clone --depth 1 --branch main \
|
git clone --branch main \
|
||||||
https://gitea.jze9.ru/jze9/anti-plagiarism.git "$SRC"
|
https://gitea.jze9.ru/jze9/anti-plagiarism.git "$SRC"
|
||||||
|
|
||||||
- name: Деплой (бэкенд 1.32 + фронтенд CT 102)
|
- name: Деплой (бэкенд 1.32 + фронтенд CT 102)
|
||||||
|
|||||||
@@ -1,28 +1,55 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# ─────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
# Деплой anti-plagiarism.
|
# Деплой anti-plagiarism (умная пересборка — только изменённых сервисов).
|
||||||
#
|
#
|
||||||
# Запускается Gitea Actions runner'ом в host-режиме прямо на app-хосте 1.32
|
# Запускается Gitea Actions runner'ом в host-режиме прямо на app-хосте 1.32
|
||||||
# (см. .gitea/workflows/deploy.yml). Ожидает:
|
# (см. .gitea/workflows/deploy.yml). Ожидает:
|
||||||
# - cwd = свежий чекаут репозитория;
|
# - cwd = ПОЛНЫЙ чекаут репозитория (нужен git-лог для diff);
|
||||||
# - переменную окружения PVE_PASSWORD (секрет Gitea) для доступа к Proxmox-хосту,
|
# - переменную PVE_PASSWORD (секрет) для доступа к Proxmox-хосту → CT 102.
|
||||||
# через который статика кладётся в CT 102 (reverse-proxy nginx).
|
|
||||||
#
|
#
|
||||||
# Что делает:
|
# Пересобирается только то, чей код изменился с прошлого деплоя (маркер SHA в
|
||||||
# 1. Синхронизирует код (services/ + scripts/) в /home/user/anti-plagiarism,
|
# $APP/.last_deploy_sha). Это критично: worker-gpu тянет torch/faiss (~2 ГБ),
|
||||||
# НЕ трогая .env и локально-правленый docker-compose.prod.yml.
|
# его нельзя пересобирать без нужды. Если менялся docker-compose.prod.yml —
|
||||||
# 2. Пересобирает и перезапускает бэкенд-сервисы (api + воркеры).
|
# пересобираются все бэкенд-сервисы.
|
||||||
# 3. Применяет миграции БД.
|
|
||||||
# 4. Собирает фронтенд (npm build) в статику.
|
|
||||||
# 5. Выкладывает статику в /var/www/academic на CT 102 (с бэкапом + reload nginx).
|
|
||||||
# ─────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
APP=/home/user/anti-plagiarism
|
APP=/home/user/anti-plagiarism
|
||||||
SRC="$(pwd)"
|
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"
|
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)"
|
echo "==> [1/5] Синхронизация кода в $APP (сохраняя .env и compose)"
|
||||||
rsync -a \
|
rsync -a \
|
||||||
@@ -30,33 +57,35 @@ rsync -a \
|
|||||||
--exclude='node_modules/' --exclude='dist/' \
|
--exclude='node_modules/' --exclude='dist/' \
|
||||||
"$SRC/services" "$SRC/scripts" "$APP/"
|
"$SRC/services" "$SRC/scripts" "$APP/"
|
||||||
|
|
||||||
echo "==> [2/5] Пересборка и перезапуск бэкенд-сервисов"
|
|
||||||
cd "$APP"
|
cd "$APP"
|
||||||
# shellcheck disable=SC2086
|
if [ -n "$REBUILD" ]; then
|
||||||
$COMPOSE up -d --build $BACKEND_SERVICES
|
echo "==> [2/5] Пересборка и перезапуск: $REBUILD"
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
$COMPOSE up -d --build $REBUILD
|
||||||
|
else
|
||||||
|
echo "==> [2/5] Бэкенд-сервисы не менялись — пропуск сборки"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "==> [3/5] Миграции БД (с ретраем, пока api поднимается)"
|
echo "==> [3/5] Миграции БД (с ретраем)"
|
||||||
for i in $(seq 1 10); do
|
for i in $(seq 1 10); do
|
||||||
if $COMPOSE exec -T api alembic upgrade head; then
|
$COMPOSE exec -T api alembic upgrade head && break
|
||||||
break
|
echo " api ещё не готов, повтор $i/10..."; sleep 5
|
||||||
fi
|
|
||||||
echo " api ещё не готов, повтор $i/10..."
|
|
||||||
sleep 5
|
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "==> [4/5] Сборка фронтенда"
|
if [ "$FRONTEND_CHANGED" = 1 ]; then
|
||||||
docker run --rm -v "$APP/services/frontend":/app -w /app node:20-slim \
|
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"
|
sh -c "npm install --no-audit --no-fund --loglevel=error && npm run build"
|
||||||
|
|
||||||
echo "==> [5/5] Выкладка статики на CT 102 (через $PVE_HOST)"
|
echo "==> [5/5] Выкладка статики на CT 102 (через $PVE_HOST)"
|
||||||
cd "$APP/services/frontend/dist"
|
cd "$APP/services/frontend/dist"
|
||||||
tar czf /tmp/academic-dist.tgz .
|
tar czf /tmp/academic-dist.tgz .
|
||||||
export SSHPASS="${PVE_PASSWORD:?PVE_PASSWORD не задан}"
|
export SSHPASS="${PVE_PASSWORD:?PVE_PASSWORD не задан}"
|
||||||
SSHOPT="-o StrictHostKeyChecking=no -o ConnectTimeout=10"
|
SSHOPT="-o StrictHostKeyChecking=no -o ConnectTimeout=10"
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
sshpass -e scp $SSHOPT /tmp/academic-dist.tgz "root@${PVE_HOST}:/tmp/academic-dist.tgz"
|
sshpass -e scp $SSHOPT /tmp/academic-dist.tgz "root@${PVE_HOST}:/tmp/academic-dist.tgz"
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
sshpass -e ssh $SSHOPT "root@${PVE_HOST}" 'bash -s' <<'REMOTE'
|
sshpass -e ssh $SSHOPT "root@${PVE_HOST}" 'bash -s' <<'REMOTE'
|
||||||
set -e
|
set -e
|
||||||
pct push 102 /tmp/academic-dist.tgz /tmp/academic-dist.tgz
|
pct push 102 /tmp/academic-dist.tgz /tmp/academic-dist.tgz
|
||||||
pct exec 102 -- bash -c '
|
pct exec 102 -- bash -c '
|
||||||
@@ -71,6 +100,10 @@ nginx -t && nginx -s reload
|
|||||||
'
|
'
|
||||||
rm -f /tmp/academic-dist.tgz
|
rm -f /tmp/academic-dist.tgz
|
||||||
REMOTE
|
REMOTE
|
||||||
rm -f /tmp/academic-dist.tgz
|
rm -f /tmp/academic-dist.tgz
|
||||||
|
else
|
||||||
|
echo "==> [4-5/5] Фронтенд не менялся — пропуск сборки и выкладки"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "==> Деплой завершён успешно"
|
echo "$CUR_SHA" > "$MARKER"
|
||||||
|
echo "==> Деплой завершён успешно (маркер обновлён: $CUR_SHA)"
|
||||||
|
|||||||
Reference in New Issue
Block a user