openspec init (config с контекстом docs-репозитория) и change slice-0-skeleton: proposal, design (11 решений без обсуждения, открытые вопросы к человеку), спеки recognition-contract, dev-environment, ci-template, tasks в порядке зависимостей между репозиториями. 06-test-data.md §6: справочники продукта — seed arm-core, не фикстуры. 09-delivery-plan.md: Срез 0 по факту (change'и, compose в docs/dev, контракт копией без общего пакета, seed). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
53 lines
4.0 KiB
Markdown
53 lines
4.0 KiB
Markdown
# 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: Шаблон параметризуется именем сервиса
|
||
Копия шаблона в `<repo>/.gitea/workflows/ci.yml` SHALL отличаться от `docs/dev/ci/python-service.yml` только блоком
|
||
`env:` (имя сервиса, порт, включение шагов arm-core); расхождение структуры шагов считается ошибкой ревью.
|
||
|
||
#### Scenario: Сверка с шаблоном
|
||
- **WHEN** ревьюер сравнивает `ci.yml` сервиса с шаблоном (`diff` без блока `env:`)
|
||
- **THEN** различий нет
|