Files
robotex/Makefile
T
protokeyandClaude Opus 5.5 cb85e5f3ab Python-клиент robotex: sync/async, сессии, задачи v2, ошибки
Пакет в client/ (зависимость — httpx), установка через pip из git или
wheel (make client-build). Тесты против api и воркера из harness.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 22:18:40 +04:00

163 lines
7.2 KiB
Makefile

VENV ?= $(HOME)/.py_envs/robotex
PYTHON := $(VENV)/bin/python
PIP := $(PYTHON) -m pip
WHEELS_DIR := wheels
REQUIREMENTS := requirements.txt
ver ?= latest
MAKECMDGOALS_TARGETS := install freeze wheels sync sync-offline clean help build release sync-dev test test-browser up down logs smoke key-create key-list key-revoke stats push
PKG := $(filter-out $(MAKECMDGOALS_TARGETS),$(MAKECMDGOALS))
.PHONY: install freeze wheels sync sync-offline clean help venv build release sync-dev test test-browser up down logs smoke key-create key-list key-revoke stats push
# образы сервисов: api — без Chrome, worker — Chrome + Xvfb; rabbitmq и redis — сторонние, кладутся в релиз
REGISTRY := docker.sokolab.xyz
API_IMAGE := robotex-api
WORKER_IMAGE := robotex-worker
DEPS_IMAGES := rabbitmq:4.1-alpine redis:8.2-alpine postgres:17-alpine
API_URL ?= http://localhost:8000
API_KEY ?=
help:
@echo "make install <pkg> [<pkg> ...] - установить пакет(ы) в $(VENV), обновить $(REQUIREMENTS), собрать wheel в $(WHEELS_DIR)/"
@echo "make sync - установить все пакеты из $(REQUIREMENTS) (из индекса)"
@echo "make sync-offline - установить все пакеты из $(REQUIREMENTS) только из $(WHEELS_DIR)/, без обращения к индексу"
@echo "make freeze - перезаписать $(REQUIREMENTS) текущим состоянием окружения"
@echo "make wheels - собрать wheel для всех пакетов из $(REQUIREMENTS)"
@echo "make clean - удалить $(WHEELS_DIR)/"
@echo "make build [ver=latest] - собрать образы $(API_IMAGE):<ver> и $(WORKER_IMAGE):<ver>"
@echo "make push ver=<ver> - собрать образы и отправить в $(REGISTRY)"
@echo "make release ver=<ver> - собрать образы и пакет для деплоя в build/<ver>/ (compose, .env, образы .tar.gz)"
@echo "make up - собрать и запустить локально: api, worker, rabbitmq, redis"
@echo "make down - остановить локальный стенд"
@echo "make logs - логи api и worker"
@echo "make smoke API_KEY=... [API_URL=...] - проверить запущенный стенд: ключ, /v1/solve, /v2/tasks, удержание окна"
@echo "make key-create name=<клиент> - выпустить API-ключ клиенту (в запущенном compose)"
@echo "make key-list - клиенты и их ключи (без самих ключей)"
@echo "make key-revoke id=<id> - отозвать ключ клиента"
@echo "make stats [days=7] - статистика: запросы, их время, время работы браузера по клиентам"
@echo "make sync-dev - установить зависимости для тестов (requirements-dev.txt)"
@echo "make test - юнит-тесты без браузера"
@echo "make client-build - собрать wheel клиента robotex в client/dist/"
@echo "make test-browser [ver=latest] - собрать образ и прогнать сквозные тесты с Chrome в Docker (нужна сеть)"
venv:
@test -d $(VENV) || python3 -m venv $(VENV)
install: venv
ifeq ($(strip $(PKG)),)
$(error Укажите пакет: make install <package>, например make install redis)
endif
$(PIP) install --upgrade $(PKG)
$(PIP) freeze > $(REQUIREMENTS)
@mkdir -p $(WHEELS_DIR)
$(PIP) wheel $(PKG) -w $(WHEELS_DIR)
@echo "Готово: $(PKG) установлен, $(REQUIREMENTS) обновлён, wheel-пакеты в $(WHEELS_DIR)/"
sync: venv
$(PIP) install -r $(REQUIREMENTS)
sync-offline: venv
$(PIP) install --no-index --find-links=$(WHEELS_DIR) -r $(REQUIREMENTS)
freeze: venv
$(PIP) freeze > $(REQUIREMENTS)
wheels: venv
@mkdir -p $(WHEELS_DIR)
$(PIP) wheel -r $(REQUIREMENTS) -w $(WHEELS_DIR)
clean:
rm -rf $(WHEELS_DIR)
build:
docker build -f Dockerfile.api -t $(API_IMAGE):$(ver) .
docker build -t $(WORKER_IMAGE):$(ver) .
push: build
for img in $(API_IMAGE) $(WORKER_IMAGE); do \
docker tag $$img:$(ver) $(REGISTRY)/$$img:$(ver) && docker push $(REGISTRY)/$$img:$(ver) || exit 1; \
done
up: build
docker compose up -d
down:
docker compose down
logs:
docker compose logs -f api worker
smoke:
$(PYTHON) tests/smoke.py $(API_URL) $(API_KEY)
key-create:
docker compose exec api python -m db.cli create "$(name)"
key-list:
docker compose exec api python -m db.cli list
key-revoke:
docker compose exec api python -m db.cli revoke $(id)
days ?= 7
stats:
docker compose exec api python -m db.cli stats --days $(days)
sync-dev: venv
$(PIP) install -r requirements-dev.txt
test:
$(PYTHON) -m pytest
client-build: venv
rm -rf client/dist client/build
$(PIP) wheel ./client -w client/dist --no-deps
@echo "Готово: client/dist/ — pip install client/dist/robotex-*.whl"
test-browser: build
docker run --rm --shm-size=2g \
-v $(CURDIR)/tests:/app/tests:ro -v $(CURDIR)/pytest.ini:/app/pytest.ini:ro \
-v $(CURDIR)/requirements-dev.txt:/app/requirements-dev.txt:ro \
-w /app $(WORKER_IMAGE):$(ver) sh -c 'pip install -q --user -r requirements-dev.txt && \
xvfb-run -a --server-args="-screen 0 1920x1080x24" python -m pytest -m browser -p no:cacheprovider -s'
RELEASE_DIR := build/$(ver)
ifneq ($(filter release push,$(MAKECMDGOALS)),)
ifeq ($(ver),latest)
$(error Укажите версию: make release ver=v0.0.2)
endif
endif
release: build
@echo "make release $(ver) -> $(RELEASE_DIR)/"
@mkdir -p $(RELEASE_DIR)
sed -e 's|image: .*$(API_IMAGE):.*|image: $(REGISTRY)/$(API_IMAGE):$(ver)|' \
-e 's|image: .*$(WORKER_IMAGE):.*|image: $(REGISTRY)/$(WORKER_IMAGE):$(ver)|' \
docker-compose.prod.yml > $(RELEASE_DIR)/docker-compose.yml
cp dot_env $(RELEASE_DIR)/.env
for img in $(DEPS_IMAGES); do docker image inspect $$img >/dev/null 2>&1 || docker pull $$img; done
# TODO: я хочу парамтером управлять сохранить в файл или отправить в свой реджестри
# if produce == file:
docker tag $(API_IMAGE):$(ver) $(REGISTRY)/$(API_IMAGE):$(ver)
docker tag $(WORKER_IMAGE):$(ver) $(REGISTRY)/$(WORKER_IMAGE):$(ver)
docker save $(REGISTRY)/$(API_IMAGE):$(ver) $(REGISTRY)/$(WORKER_IMAGE):$(ver) $(DEPS_IMAGES) | gzip > $(RELEASE_DIR)/robotex-$(ver).tar.gz
# else:
# docker push docker.sokolab.xyz/$(API_IMAGE):$(ver) docker.sokolab.xyz/$(WORKER_IMAGE):$(ver) docker.sokolab.xyz/$(DEPS_IMAGES)
@printf '%s\n' \
'# Robotex $(ver)' \
'' \
'```bash' \
'docker load -i robotex-$(ver).tar.gz' \
'docker compose up -d' \
'```' \
'' \
'Настройки (порт, слоты, CPU и память воркера, пароли RabbitMQ и Postgres) — в .env.' \
'Ключ клиенту: docker compose exec api python -m db.cli create <имя>' > $(RELEASE_DIR)/README.md
@echo "Готово: $(RELEASE_DIR)/"
# позволяет передавать имя пакета как аргумент: make install redis
%:
@: