up
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
.PHONY: check build prod-build publish venue venue-update venue-https
|
.PHONY: check build prod-build publish dev game stop venue venue-update venue-https
|
||||||
|
|
||||||
PROD_DIR ?= prod
|
PROD_DIR ?= prod
|
||||||
|
|
||||||
@@ -25,6 +25,14 @@ venue:
|
|||||||
|
|
||||||
venue-update venue-https: venue
|
venue-update venue-https: venue
|
||||||
|
|
||||||
|
dev:
|
||||||
|
bash scripts/dev.sh
|
||||||
|
|
||||||
|
game: venue
|
||||||
|
|
||||||
|
stop:
|
||||||
|
docker compose -f venue/docker-compose.yml -f venue/docker-compose.https.yml --env-file venue/.env down
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
@test -n "$(MSG)" || (echo 'Usage: make publish MSG="commit message"' >&2; exit 1)
|
@test -n "$(MSG)" || (echo 'Usage: make publish MSG="commit message"' >&2; exit 1)
|
||||||
@$(MAKE) build
|
@$(MAKE) build
|
||||||
|
|||||||
@@ -18,6 +18,22 @@
|
|||||||
|
|
||||||
Требования: Go, Docker Compose, Node.js 20.19+ или 22.12+, npm.
|
Требования: Go, Docker Compose, Node.js 20.19+ или 22.12+, npm.
|
||||||
|
|
||||||
|
Короткие команды из корня проекта:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make dev # разработка: локальные БД/RustFS, Go-бэкенд и Vite-фронтенд
|
||||||
|
make game # локальная игра: запуск venue с HTTPS из готовых артефактов
|
||||||
|
make stop # остановка venue, данные сохраняются
|
||||||
|
```
|
||||||
|
|
||||||
|
`make dev` запускает приложения в текущем терминале; `Ctrl+C` останавливает оба
|
||||||
|
приложения, БД и RustFS остаются запущены. Перед первым запуском подготовьте
|
||||||
|
зависимости и `.env` по инструкции ниже; схема БД должна быть подготовлена через
|
||||||
|
`make -C evening_detective_server migrate-up` (требуется Goose).
|
||||||
|
`make game` — алиас `make venue`: перед первым запуском нужны сборка
|
||||||
|
`make prod-build`, сертификат и локальный DNS, как описано в разделе площадки.
|
||||||
|
`make stop` останавливает только площадку; процессы разработки не затрагивает.
|
||||||
|
|
||||||
### 1. Зависимости сервера
|
### 1. Зависимости сервера
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -104,7 +120,7 @@ DNS по `http://<VENUE_BIND_IP>:<VENUE_PORT>`. Ссылки на материа
|
|||||||
Миграции Goose выполняются до старта приложения. Для остановки без потери данных:
|
Миграции Goose выполняются до старта приложения. Для остановки без потери данных:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker compose -f venue/docker-compose.yml -f venue/docker-compose.https.yml --env-file venue/.env down
|
make stop
|
||||||
```
|
```
|
||||||
|
|
||||||
Не используйте `down -v`: это удаляет данные. После изменений кода или миграций
|
Не используйте `down -v`: это удаляет данные. После изменений кода или миграций
|
||||||
|
|||||||
+1
-1
Submodule prod updated: 1400500d50...4205e86ef6
@@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.."
|
||||||
|
if [[ ! -f evening_detective_server/.env ]]; then
|
||||||
|
echo 'Сначала скопируйте evening_detective_server/.env.example в evening_detective_server/.env.' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ! -d evening_detective_frontend/node_modules ]]; then
|
||||||
|
echo 'Сначала выполните npm --prefix evening_detective_frontend ci.' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker compose -f evening_detective_server/docker-compose-db.yml up -d --wait
|
||||||
|
|
||||||
|
# Отдельные группы позволяют остановить и go run/npm, и их дочерние процессы.
|
||||||
|
set -m
|
||||||
|
pids=()
|
||||||
|
cleanup() {
|
||||||
|
trap - EXIT INT TERM
|
||||||
|
for pid in "${pids[@]}"; do
|
||||||
|
kill -TERM -- "-$pid" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
wait || true
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
trap 'exit 130' INT
|
||||||
|
trap 'exit 143' TERM
|
||||||
|
|
||||||
|
make -C evening_detective_server run &
|
||||||
|
pids+=("$!")
|
||||||
|
(cd evening_detective_frontend && exec npm run dev) &
|
||||||
|
pids+=("$!")
|
||||||
|
echo 'Разработка: http://localhost:5173; API: http://localhost:8090. Остановка: Ctrl+C.'
|
||||||
|
wait -n "${pids[@]}"
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
"""Check development startup/cleanup with stubs; never touch running services."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import signal
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
with tempfile.TemporaryDirectory(prefix='detective-dev-') as directory:
|
||||||
|
root = Path(directory)
|
||||||
|
(root / 'scripts').mkdir()
|
||||||
|
(root / 'scripts/dev.sh').write_text((ROOT / 'scripts/dev.sh').read_text())
|
||||||
|
(root / 'evening_detective_server').mkdir()
|
||||||
|
(root / 'evening_detective_frontend/node_modules').mkdir(parents=True)
|
||||||
|
bin_dir = root / 'bin'
|
||||||
|
bin_dir.mkdir()
|
||||||
|
log = root / 'commands.log'
|
||||||
|
env = {**os.environ, 'PATH': str(bin_dir) + os.pathsep + os.environ['PATH'], 'TEST_LOG': str(log)}
|
||||||
|
for name in ['docker', 'make', 'npm']:
|
||||||
|
stub = bin_dir / name
|
||||||
|
stub.write_text(
|
||||||
|
'#!/usr/bin/env bash\n'
|
||||||
|
f'echo "{name} $*" >> "$TEST_LOG"\n' +
|
||||||
|
('exit 0\n' if name == 'docker' else
|
||||||
|
f'trap \'echo "{name} stopped" >> "$TEST_LOG"; exit 0\' TERM\n'
|
||||||
|
'sleep 60 &\n'
|
||||||
|
'wait\n')
|
||||||
|
)
|
||||||
|
stub.chmod(0o755)
|
||||||
|
|
||||||
|
script = str(root / 'scripts/dev.sh')
|
||||||
|
result = subprocess.run(['bash', script], env=env, capture_output=True, text=True)
|
||||||
|
assert result.returncode != 0 and '.env.example' in result.stderr
|
||||||
|
assert not log.exists(), 'Missing config must fail before Docker'
|
||||||
|
(root / 'evening_detective_server/.env').touch()
|
||||||
|
|
||||||
|
def wait_for(text):
|
||||||
|
deadline = time.monotonic() + 5
|
||||||
|
while time.monotonic() < deadline:
|
||||||
|
if log.exists() and text in log.read_text():
|
||||||
|
return
|
||||||
|
time.sleep(.05)
|
||||||
|
raise AssertionError('Missing log entry: ' + text)
|
||||||
|
|
||||||
|
for sig in [signal.SIGINT, signal.SIGTERM]:
|
||||||
|
log.unlink(missing_ok=True)
|
||||||
|
process = subprocess.Popen(['bash', script], env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
try:
|
||||||
|
wait_for('npm run dev')
|
||||||
|
wait_for('make -C evening_detective_server run')
|
||||||
|
process.send_signal(sig)
|
||||||
|
process.communicate(timeout=5)
|
||||||
|
assert process.returncode == 128 + sig
|
||||||
|
commands = log.read_text()
|
||||||
|
assert 'compose -f evening_detective_server/docker-compose-db.yml up -d --wait' in commands
|
||||||
|
assert 'make stopped' in commands and 'npm stopped' in commands, commands
|
||||||
|
finally:
|
||||||
|
if process.poll() is None:
|
||||||
|
process.send_signal(signal.SIGTERM)
|
||||||
|
process.communicate(timeout=5)
|
||||||
|
|
||||||
|
(bin_dir / 'make').write_text('#!/bin/sh\nsleep .2\nexit 7\n')
|
||||||
|
log.unlink(missing_ok=True)
|
||||||
|
result = subprocess.run(['bash', script], env=env, capture_output=True, timeout=5)
|
||||||
|
assert result.returncode == 7
|
||||||
|
assert 'npm stopped' in log.read_text(), 'Backend failure must stop frontend'
|
||||||
|
|
||||||
|
stop = subprocess.check_output(['make', '-n', 'stop'], cwd=ROOT, text=True)
|
||||||
|
assert 'venue/docker-compose.yml' in stop and 'venue/docker-compose.https.yml' in stop
|
||||||
|
assert '--env-file venue/.env down' in stop and '-v' not in stop.split()
|
||||||
|
game = subprocess.check_output(['make', '-n', 'game'], cwd=ROOT, text=True)
|
||||||
|
assert game.strip() == 'bash venue/deploy.sh'
|
||||||
|
dev = subprocess.check_output(['make', '-n', 'dev'], cwd=ROOT, text=True)
|
||||||
|
assert dev.strip() == 'bash scripts/dev.sh'
|
||||||
|
print('PASS: command aliases, config preflight, startup, Ctrl+C/SIGTERM cleanup, backend failure; stop preserves volumes')
|
||||||
Reference in New Issue
Block a user