Files
robotex/Makefile
T
protokeyandClaude Opus 5.5 0e10fb671d fix: reCAPTCHA — закрытие окна с картинками и вызов callback (#10)
- Окно с картинками закрывается кликом в угол подложки: в её центре лежит
  само окно и перехватывает клик (Locator.click падал по таймауту 60 с).
- form_submit выполняется в основном мире страницы (isolated_context=False):
  префикс "mw:" patchright не поддерживает, в изолированном мире
  ___grecaptcha_cfg не виден — "Recaptcha callback function not found".
- Воркер: LOG_LEVEL выставляется корневому логгеру явно — dramatiq настраивает
  логирование раньше, и basicConfig ничего не делал. make dev — LOG_LEVEL=DEBUG.
- test_main.http: запрос на zennolab с проверкой результата по #main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 01:17:06 +04:00

198 lines
9.4 KiB
Makefile
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 dev dev-deps dev-key
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 dev dev-deps dev-key
# образы сервисов: 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 ?=
# make dev (#90): rabbitmq, redis, postgres — в Docker с портами на 127.0.0.1 (docker-compose.dev.yml), api и worker —
# на хосте, Chrome открывается на рабочем столе. Порты нестандартные: 5672/5432/8000 часто заняты другими проектами.
DEV_COMPOSE := docker compose -f docker-compose.yml -f docker-compose.dev.yml
DEV_API_PORT ?= 8010
DEV_RABBITMQ_PORT ?= 5673
DEV_REDIS_PORT ?= 6380
DEV_POSTGRES_PORT ?= 5433
# окон Chrome на рабочем столе; потоков dramatiq — вдвое больше, как в Dockerfile
DEV_SLOTS ?= 2
RABBITMQ_PASSWORD ?= robotex
POSTGRES_PASSWORD ?= robotex
export DEV_RABBITMQ_PORT DEV_REDIS_PORT DEV_POSTGRES_PORT RABBITMQ_PASSWORD POSTGRES_PASSWORD
DEV_ENV := RABBITMQ_URL=amqp://robotex:$(RABBITMQ_PASSWORD)@localhost:$(DEV_RABBITMQ_PORT)/ \
REDIS_URL=redis://localhost:$(DEV_REDIS_PORT)/0 \
DATABASE_URL=postgresql+asyncpg://robotex:$(POSTGRES_PASSWORD)@localhost:$(DEV_POSTGRES_PORT)/robotex \
BROWSER_SLOTS=$(DEV_SLOTS) \
LOG_LEVEL=DEBUG
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 dev - api и worker на хосте с видимым Chrome, rabbitmq/redis/postgres в Docker; API на :$(DEV_API_PORT)"
@echo "make dev-key name=<клиент> - выпустить API-ключ клиенту при make dev"
@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
# контейнерные api и worker останавливаются: иначе worker в Docker тоже берёт задачи из общей очереди и выполняет их невидимо
dev-deps:
-docker compose stop api worker
$(DEV_COMPOSE) up -d --wait rabbitmq redis postgres
# Ctrl+C останавливает оба процесса; инфраструктура остаётся запущенной (make down — остановить)
dev: dev-deps
cd src && export $(DEV_ENV) && \
{ $(PYTHON) -m uvicorn main:app --reload --port $(DEV_API_PORT) & api=$$!; \
trap 'kill $$api 2>/dev/null' EXIT INT TERM; \
$(PYTHON) -m dramatiq worker.actors --processes 1 --threads $$(( $(DEV_SLOTS) * 2 )); }
dev-key: dev-deps
cd src && $(DEV_ENV) $(PYTHON) -m db.cli create "$(name)"
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
%:
@: