ci: авто-деплой в прод через Gitea Actions (push в main)
Some checks failed
Deploy / deploy (push) Failing after 8m6s

Self-hosted act_runner в host-режиме на app-хосте 1.32 (label "deploy").
При пуше в main workflow клонирует коммит и запускает scripts/deploy.sh:
синхронизация кода → пересборка/перезапуск бэкенд-сервисов → миграции →
сборка фронтенда → выкладка статики на CT 102 (reverse-proxy) с бэкапом.

Доступ к Proxmox-хосту для CT 102 — через секрет PVE_PASSWORD.
Больше ручных rsync/rebuild — деплой по git push.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jze9
2026-07-29 13:23:04 +05:00
parent b0e1eadcbb
commit 34fa495fb1
2 changed files with 113 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
name: Deploy
# Авто-деплой в прод при пуше в main.
# Джоба выполняется на self-hosted runner'е в host-режиме прямо на app-хосте
# 1.32 (label "deploy"), поэтому имеет доступ к его docker и сети до Proxmox.
on:
push:
branches: [main]
workflow_dispatch: {}
concurrency:
group: deploy-prod
cancel-in-progress: false
jobs:
deploy:
runs-on: deploy
steps:
- name: Клонировать текущий коммит
run: |
set -euo pipefail
SRC="$(mktemp -d)"
echo "SRC=$SRC" >> "$GITHUB_ENV"
git clone --depth 1 --branch main \
https://gitea.jze9.ru/jze9/anti-plagiarism.git "$SRC"
- name: Деплой (бэкенд 1.32 + фронтенд CT 102)
env:
PVE_PASSWORD: ${{ secrets.PVE_PASSWORD }}
run: |
set -euo pipefail
cd "$SRC"
bash scripts/deploy.sh
- name: Убрать временный чекаут
if: always()
run: rm -rf "${SRC:-/tmp/none}"

76
scripts/deploy.sh Executable file
View File

@@ -0,0 +1,76 @@
#!/usr/bin/env bash
# ─────────────────────────────────────────────────────────────────────────────
# Деплой anti-plagiarism.
#
# Запускается Gitea Actions runner'ом в host-режиме прямо на app-хосте 1.32
# (см. .gitea/workflows/deploy.yml). Ожидает:
# - cwd = свежий чекаут репозитория;
# - переменную окружения PVE_PASSWORD (секрет Gitea) для доступа к Proxmox-хосту,
# через который статика кладётся в CT 102 (reverse-proxy nginx).
#
# Что делает:
# 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).
# ─────────────────────────────────────────────────────────────────────────────
set -euo pipefail
APP=/home/user/anti-plagiarism
SRC="$(pwd)"
PVE_HOST=192.168.20.254 # Proxmox-хост, через pct exec которого живёт CT 102
COMPOSE="docker compose -f docker-compose.prod.yml"
BACKEND_SERVICES="api worker-gpu worker-indexer worker-notifier worker-gost"
echo "==> [1/5] Синхронизация кода в $APP (сохраняя .env и compose)"
rsync -a \
--exclude='__pycache__/' --exclude='*.pyc' --exclude='.pytest_cache/' \
--exclude='node_modules/' --exclude='dist/' \
"$SRC/services" "$SRC/scripts" "$APP/"
echo "==> [2/5] Пересборка и перезапуск бэкенд-сервисов"
cd "$APP"
# 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
fi
echo " api ещё не готов, повтор $i/10..."
sleep 5
done
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"
echo "==> [5/5] Выкладка статики на CT 102 (через $PVE_HOST)"
cd "$APP/services/frontend/dist"
tar czf /tmp/academic-dist.tgz .
export SSHPASS="${PVE_PASSWORD:?PVE_PASSWORD не задан}"
SSHOPT="-o StrictHostKeyChecking=no -o ConnectTimeout=10"
# shellcheck disable=SC2086
sshpass -e scp $SSHOPT /tmp/academic-dist.tgz "root@${PVE_HOST}:/tmp/academic-dist.tgz"
# shellcheck disable=SC2086
sshpass -e ssh $SSHOPT "root@${PVE_HOST}" 'bash -s' <<'REMOTE'
set -e
pct push 102 /tmp/academic-dist.tgz /tmp/academic-dist.tgz
pct exec 102 -- bash -c '
set -e
cd /var/www
cp -a academic "academic.bak.$(date +%s)"
cd academic
rm -rf assets index.html
tar xzf /tmp/academic-dist.tgz
chown -R 1000:1000 .
nginx -t && nginx -s reload
'
rm -f /tmp/academic-dist.tgz
REMOTE
rm -f /tmp/academic-dist.tgz
echo "==> Деплой завершён успешно"