# Spec Delta: ci-template ## Purpose Единый шаблон CI (Gitea Actions) для сервисных репозиториев АРМ КА: какие проверки обязательны, в каком порядке и с какими внешними ресурсами они выполняются, чтобы PR в любой из трёх репозиториев проверялся одинаково. ## ADDED Requirements ### Requirement: Обязательные проверки Python-сервиса Шаблон `docs/dev/ci/python-service.yml` SHALL выполнять на каждый push в ветку и PR в `main`: установку зависимостей из `api/requirements.txt` и `api/requirements-dev.txt`; `ruff check` и `ruff format --check` по `api/`; `mypy api/src`; `pytest` из `api/` с сервисами PostgreSQL 15, NATS 2.10 (JetStream) и MinIO, доступными по переменным `OPENBAO__*`; тест идентичности вендоренного контракта с `docs/contracts`; сборку образа `docker build` без push. #### Scenario: PR с нарушением формата - **WHEN** в PR есть файл, не отформатированный `ruff format` - **THEN** job `lint` падает до запуска тестов, остальные job'ы не стартуют #### Scenario: Зелёный PR - **WHEN** все проверки проходят - **THEN** статус PR в Gitea — success, артефакт отчёта pytest (junit) прикреплён к run ### Requirement: Дополнительные проверки arm-core Для `arm-core` шаблон SHALL дополнительно: применить миграции с нуля (`alembic upgrade head`) к пустой БД, откатить (`alembic downgrade base`) и применить снова; запустить `api/scripts/check_dbml_vs_orm.py` против `docs/model/data-model-v5.13.dbml`; выполнить job `web`: `npm ci`, `npx biome check src`, `npx tsc --noEmit`, `npm run build`. #### Scenario: Расхождение ORM и DBML - **WHEN** в ORM добавлена колонка, которой нет в DBML - **THEN** шаг `check_dbml_vs_orm` падает с перечнем расхождений, PR красный #### Scenario: Миграция без отката - **WHEN** `downgrade` ревизии не удаляет созданный ею объект - **THEN** шаг «upgrade → downgrade → upgrade» падает ### Requirement: Доступ к соседним репозиториям Шаблон SHALL получать `arm-ka-docs` (для контракта и DBML) и `arm-ka-fixtures` (для тестов на реальных данных) checkout'ом в `../docs` и `../fixtures` c токеном только на чтение из секретов репозитория (`DOCS_TOKEN`, `FIXTURES_TOKEN`); при отсутствии секрета фикстурные тесты SHALL пропускаться с явным предупреждением, а не падать. #### Scenario: Нет доступа к фикстурам - **WHEN** секрет `FIXTURES_TOKEN` не задан - **THEN** тесты с маркером `fixtures` помечены skipped с причиной «ARM_KA_FIXTURES недоступен», остальные выполняются ### Requirement: Шаблон параметризуется именем сервиса Копия шаблона в `/.gitea/workflows/ci.yml` SHALL отличаться от `docs/dev/ci/python-service.yml` только блоком `env:` (имя сервиса, порт, включение шагов arm-core); расхождение структуры шагов считается ошибкой ревью. #### Scenario: Сверка с шаблоном - **WHEN** ревьюер сравнивает `ci.yml` сервиса с шаблоном (`diff` без блока `env:`) - **THEN** различий нет