17 KiB
Проверки качества: цели make и порядок перед PR
Конфигураций CI в репозиториях нет (в Gitea CI не используется, пайплайн платформы банка вне зоны проекта), поэтому
проверки выполняются локально одной командой перед каждым PR. Требования — spec quality-checks
(openspec/specs/quality-checks/spec.md), решение D-8 (openspec/changes/archive/2026-10-04-slice-0-skeleton/design.md).
Все цели запускаются из корня репозитория сервиса (arm-core, tabular-parser, scan-gateway); рецепты сами
переходят в api/ и используют окружение api/.venv. Инфраструктура compose — docs/dev/docker-compose.yml
(см. README.md); в workspace и в worktree .wt/<срез>/ она лежит рядом как ../docs/dev/.
Общие цели
Одинаковый набор целей во всех трёх сервисных репозиториях; семантика, описанная ниже, — эталонная (реализации расходятся в деталях, см. «Известные расхождения реализаций»). Репозиторий вправе добавлять свои цели (см. ниже), но не меняет смысл общих.
| Цель | Что делает | Нужен Docker / compose |
|---|---|---|
make venv |
api/.venv на Python 3.11 через uv; ставит requirements.txt без строк raisa_* (пакеты Nexus банка вне банка недоступны, D-10) и requirements-dev.txt |
нет |
make lint |
ruff check ., ruff format --check ., mypy src (в arm-core — mypy src scripts) |
нет |
make test |
pytest -m "not integration": юнит-тесты; включает тест идентичности вендоренного контракта api/contracts/ с ../docs/contracts |
нет |
make test-integration |
pytest -m integration против инфраструктуры compose (PostgreSQL 16, NATS, MinIO; бакет arm-ka должен существовать, его создаёт make up) |
да, make up |
make check |
make lint затем make test; останавливается на первой упавшей проверке (только при последовательном запуске: lint и test — пререквизиты, при make -j они идут параллельно) |
нет |
make check-full |
make check + make test-integration + сборка docker-образа (docker build); для arm-core — расширенный набор, см. ниже |
да, make up и Docker |
make up |
поднимает инфраструктуру из ../docs/dev/docker-compose.yml; постоянные сервисы postgres, nats, minio |
Docker |
Сводка шагов make check: ruff check . → ruff format --check . → mypy src (в arm-core — mypy src scripts) →
pytest -m "not integration".
Любой ненулевой код останавливает цель на этом шаге, следующие не выполняются. Запускайте без -j: при параллельной сборке шаги идут одновременно. make check не требует Docker,
PostgreSQL, NATS и сети.
make up
Поднимает compose-проект arm-ka (имя зафиксировано в compose, поэтому тома общие для любого worktree):
docker compose -f ../docs/dev/docker-compose.yml --project-name arm-ka up -d --wait postgres nats minio
docker compose -f ../docs/dev/docker-compose.yml --project-name arm-ka run --rm minio-init # бакет arm-ka (идемпотентно)
Почему так: голый docker compose up -d --wait возвращает код 1 (одноразовый minio-init завершается кодом 0, compose
считает это сбоем), поэтому --wait даётся со списком долгоживущих сервисов, а бакет создаётся отдельным шагом. Без
бакета интеграционные тесты на свежем томе падают на NoSuchBucket. Целей down/stop/restart нет намеренно: проект
arm-ka общий для всех сервисов; остановка и сброс — вручную (docker compose --profile services down, при сбросе данных down -v с тем же --profile services,
иначе контейнеры сервисов останутся), см. README.md.
Эталонная реализация
make up— вscan-gateway. Реализации вarm-coreиtabular-parserотличаются (см. «Известные расхождения реализаций»).
Состав make check-full по репозиториям
| Репозиторий | Шаги по порядку |
|---|---|
scan-gateway |
check → test-integration → docker-build (образ scan-gateway:dev); интеграционный тест поднимает эмулятор ИС Сканирование в процессе теста |
tabular-parser |
check → test-integration → docker-build (образ tabular-parser) |
arm-core |
check → dbml-check → check-infra → test-integration → docker-build → web-check |
Для arm-core дополнительно:
dbml-check—python scripts/check_dbml_vs_orm.py ../../docs/model/data-model-v5.18.dbml(путь отapi/, по умолчанию — переменнаяDBMLMakefile, она указывает на текущую версию модели; другой —make dbml-check DBML=<путь относительно api/>): ORM обязана совпадать с DBML; расхождения печатаются построчно, код 1.- Цикл миграций «
alembic upgrade head→alembic downgrade base→alembic upgrade head» на чистой БД, пустой autogenerate и сверка схемы сcreate_allORM выполняетtests/test_migrations.py; он входит вtest-integration, поэтому отдельным шагом вcheck-fullне гоняется. Для быстрой проверки одних миграций:make migration-cycle. check-infra— TCP-проверка доступности PostgreSQL и NATS изapi/.env.test; вместо длинного трейсбека pytest подсказывает «поднимите инфраструктуру:make up».web-check—npm install,biome check src,tsc --noEmit,npm run buildвweb/.
Дополнительные цели репозиториев (не общие): arm-core — migrate, seed, seed-dev, dbml-check,
migration-cycle, check-infra, docker-build, web-check; scan-gateway — help, docker-build, emulator;
tabular-parser — docker-build.
Эталонный фрагмент dev/Makefile.common
Рецепты общих целей вынесены в Makefile.common — это эталон (источник — Makefile scan-gateway),
с которым сервис сверяется diffом или который подключает напрямую:
# Makefile сервиса: свои переменные и цели; цель по умолчанию задана явно, иначе ею станет первая цель include (venv)
.DEFAULT_GOAL := check
MYPY_PATHS := src scripts # arm-core; по умолчанию src
CHECK_FULL_STEPS := check dbml-check check-infra test-integration docker-build web-check # arm-core
include ../docs/dev/Makefile.common
Переменные (все ?=): VENV, BIN, MYPY_PATHS, COMPOSE_FILE, COMPOSE_PROJECT, IMAGE (по умолчанию имя каталога
сервиса; у scan-gateway — scan-gateway:dev), CHECK_FULL_STEPS (по умолчанию check test-integration docker-build).
Определяет цели venv, lint, test, test-integration, check, docker-build, check-full, up.
Цели, специфичные для сервиса (migrate, seed, dbml-check, check-infra, web-check, emulator, help),
остаются в его Makefile.
Проверка «make check вызывает одинаковые команды»: make -n <цель> в каждом сервисе и в Makefile, подключающем
Makefile.common с теми же переменными, даёт одинаковый вывод. Текущее состояние (Срез 0, сервисы не менялись):
scan-gateway совпадает с эталоном полностью; arm-core и tabular-parser — по venv, lint, test,
test-integration, check, docker-build и составу команд check-full, но не по up и по структуре check-full
(пререквизиты вместо вызовов $(MAKE)); см. «Известные расхождения реализаций». Сервисы переходят на include в
следующих срезах (решение 24 в design.md).
Внешние ресурсы: docs и fixtures опциональны
Проверки сервисов обращаются к соседним репозиториям workspace и не должны падать, если их нет: тест
пропускается (skipped) с явной причиной, остальные выполняются, make check остаётся зелёным.
| Что | Где ищется | Что пропускается без него |
|---|---|---|
docs |
../docs или каталог из ARM_KA_DOCS |
тест идентичности контракта api/contracts/ с docs/contracts/; в arm-core ещё сверка с DBML в тестах (dbml-check как цель make требует DBML и падает без него) |
fixtures |
../fixtures или каталог из ARM_KA_FIXTURES (в arm-core; в остальных сервисах — см. «Известные расхождения реализаций») |
тесты с маркером fixtures (реальные данные, внутренний доступ): причина пропуска — «ARM_KA_FIXTURES недоступен …» (в arm-core) |
Пример (docs и fixtures лежат не рядом):
export ARM_KA_DOCS=/path/to/arm-ka-docs
export ARM_KA_FIXTURES=/path/to/arm-ka-fixtures
make check
Причины пропусков видно в выводе (pytest --verbose в addopts: строки SKIPPED (…)); полный список —
cd api && .venv/bin/pytest -m "not integration" -rs.
Важно: зелёный make check с пропусками не доказывает идентичность контракта и прохождение на реальных данных. Перед
PR убедитесь, что docs и fixtures доступны (пропусков по этим причинам нет) либо явно укажите в описании PR, что
пропущено.
Фактическая поддержка переменных различается по репозиториям — см. «Известные расхождения реализаций».
Проверки этого репозитория (docs)
В репозитории arm-ka-docs нет сервисных целей; Makefile в его корне содержит только проверки спеки и контракта:
| Цель | Что делает |
|---|---|
make venv |
.venv (Python 3.11, uv) с jsonschema — единственной зависимостью скриптов |
make validate-contracts |
python scripts/validate_contracts.py: примеры contracts/examples/ против трёх схем JSON Schema 2020-12 (3 схемы, 8 примеров); код 1 при любой ошибке |
make validate-openspec |
openspec validate slice-0-skeleton --strict (другое изменение: make validate-openspec CHANGE=<id>) |
make check |
обе проверки выше |
Без make: python scripts/validate_contracts.py (нужен jsonschema) и openspec validate <id> --strict.
Менять contracts/** нужно осознанно: байтовые копии схем лежат в api/contracts/ каждого сервиса, после правки их
нужно пересинхронизировать (cp), иначе тест идентичности в сервисах упадёт.
Порядок перед PR
- Поднять инфраструктуру:
make up(в репозитории сервиса). Убедиться, чтоdocsиfixturesдоступны (рядом или черезARM_KA_DOCS,ARM_KA_FIXTURES— последняя поддерживается только вarm-core, см. «Известные расхождения реализаций»). make check— быстрые проверки. Исправлять до зелёного.make check-full— полная проверка (интеграционные тесты, образ; дляarm-core— ещё DBML, миграции,web).- Если менялись
contracts/,model/или спека в репозиторииdocs: в нёмmake check, затем в каждом затронутом сервисе — пересинхронизация копий контракта и пункты 2–3. - Итог
make check-full(зелёный/красный, число тестов, что пропущено и почему) вписать в описание PR.
Правила: PR создаётся только после зелёного make check-full; один OpenSpec change и один PR — на один репозиторий;
make check-full не заменяет ревью.
Типичные проблемы
make test-integrationпадает на соединении — не поднята инфраструктура:make up; порты заняты — поменять вdocs/dev/.envи вapi/.env.test/api/.envсервиса (README.md).NoSuchBucket— бакета нет на свежем томе:docker compose -f ../docs/dev/docker-compose.yml --project-name arm-ka run --rm minio-init.tabular-parser: интеграционный тест получает чужие ответы — на шине compose не должно работать другого экземпляра сервиса из той же queue group (интеграционный тест поднимает сервис в процессе теста).- Нет
uv/Python 3.11 —make venvих требует (версия Python — как на платформе). docker build(иnpm installвweb-checkуarm-core) падает без сети — это шагиcheck-full, которым нужна сеть (образы, пакеты);make checkсети не требует.
Известные расхождения реализаций
Фактические реализации в Makefile трёх сервисов расходятся с описанной выше семантикой. Сервисы в рамках Среза 0
не менялись; расхождения занесены как находки ревью.
make up. Эталон —scan-gateway(--project-name arm-ka,--waitсо списком сервисов, затемrun --rm minio-init).tabular-parserне создаёт бакет (нет шагаminio-init) и на свежем томе даётNoSuchBucket;arm-coreвыполняетdocker compose up -dбез--wait, то есть возвращается до готовности сервисов.- Структура
check-full. Вscan-gatewayшаги вызываются через$(MAKE)(порядок и остановка на первой ошибке гарантированы и приmake -j); вarm-coreиtabular-parser— пререквизитами (при последовательном запуске эквивалентно, приmake -jпорядок не гарантирован). Запускайте без-j. ARM_KA_DOCS/ARM_KA_FIXTURES.arm-coreучитывает обе переменные;tabular-parser— толькоARM_KA_DOCS(тестов с маркеромfixturesпока нет);scan-gateway— ни одну (ищет../docsи../fixtures/ocrпо фиксированному пути; тексты причин пропуска не содержат «ARM_KA_FIXTURES недоступен»). Пока расхождение не устранено, дляscan-gatewaydocs/fixtures нужно класть рядом.