Files
dzentra_bot/docs/operations/ci_gate.md

194 lines
10 KiB
Markdown
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.
# CI gate Dzentra
**Статус:** Repository implementation complete; Canary Pending
**Область:** CI-GATE.0CI-GATE.2
**Дата фактической проверки Gitea:** 2026-08-04
---
## 1. Что означает CI gate
CI gate — автоматический барьер качества между изменением кода и его
принятием в `main`. Он не доказывает отсутствие любых ошибок, но не даёт
считать изменение готовым, пока обязательные воспроизводимые проверки не
завершились успешно.
Первый gate Dzentra вводится безопасно, в два шага:
1. repository-side contract фиксируется и проверяется локально;
2. после отдельного разрешения он публикуется и вручную запускается на
реальном Gitea runner как canary.
До зелёного canary workflow не запускается автоматически и не участвует в
branch protection.
## 2. Состав CI-GATE.0CI-GATE.2
| Этап | Смысл | Текущий статус |
|---|---|---|
| CI-GATE.0 | Проверить готовность Gitea/runner и зафиксировать ручной canary contract | Repository часть готова; runner и серверный запуск не подтверждены |
| CI-GATE.1 | Создать единый hash-locked набор developer/CI dependencies | Реализовано локально |
| CI-GATE.2 | Добавить три независимые обязательные проверки без внешних сервисов | Реализовано локально; Canary Pending |
Зелёный canary означает реальный успешный запуск всех трёх jobs, а не
только корректный локальный YAML или зелёные локальные тесты.
## 3. Фактическое состояние CI-GATE.0
Read-only проверка публичного сервера подтвердила:
- репозиторий находится на Gitea 1.25.5;
- вкладка Actions доступна;
- до добавления этого contract сервер показывал «Пока нет рабочих
процессов»;
- версия, регистрация и labels `act_runner` без административного доступа
не видны и поэтому не считаются подтверждёнными.
На данном этапе не изменялись настройки Gitea, Actions, runner registration
или branch protection.
Workflow использует объявленный repository contract label
`dzentra-python312`. Runner с этим label должен предоставлять изолированную
Linux-среду со следующими компонентами:
- Python 3.12, `venv` и `pip`;
- Bash, Git и CA certificates;
- Node.js 20 для `actions/checkout` v4;
- GNU `timeout`;
- возможность слушать временный socket только на `127.0.0.1`;
- отсутствие privileged mode и подключённого Docker socket.
До отдельного подтверждения нельзя регистрировать runner или подбирать его
label «на глаз». Если runner отсутствует, jobs останутся в очереди — это
ожидаемый незакрытый инфраструктурный пункт, а не зелёный результат.
## 4. Hash-locked developer/CI environment
Читаемый источник прямых зависимостей остаётся в
[`app/requirements-dev.txt`](../../app/requirements-dev.txt). Установка для
разработки и CI выполняется только из
[`app/requirements-dev.lock`](../../app/requirements-dev.lock):
```bash
python3.12 -m venv app/.venv
app/.venv/bin/python -m pip install \
--require-hashes \
-r app/requirements-dev.lock
app/.venv/bin/python -m pip check
```
Developer lock сохраняет все версии Production lock и добавляет только
инструменты разработки с их транзитивными зависимостями. Это предотвращает
ситуацию, когда CI тестирует приложение на более новых Production-библиотеках,
чем Production image.
Регенерация выполняется намеренно из корня репозитория:
```bash
uv pip compile app/requirements-dev.txt \
--constraints app/requirements.lock \
--generate-hashes \
--universal \
--python-version 3.12 \
--no-header \
--no-annotate \
--output-file app/requirements-dev.lock
```
После генерации в начале файла сохраняются только три служебные строки на
русском языке. Любое изменение lock-файла рассматривается как dependency
update и требует отдельного diff review.
## 5. Контракт CI-GATE.2
Workflow находится в
[`ci-required.yml`](../../.gitea/workflows/ci-required.yml) и пока имеет
только `workflow_dispatch`. Его стабильные jobs:
| Job | Проверяет | Не использует |
|---|---|---|
| `quality` | `pip check`, Pyright, documentation gate, static tests, `compileall`, whitespace | сеть приложения, PostgreSQL, Docker |
| `offline-regression` | полную default pytest-регрессию | integration, stress, live |
| `loopback-integration` | локальные WebSocket/reconnect/recovery scenarios | внешние endpoints и PostgreSQL |
Все потенциально долгие shell-команды ограничены GNU `timeout`. Это
обязательно, потому что Gitea 1.25.5 игнорирует GitHub-совместимое поле
`timeout-minutes`. По той же причине workflow не использует вводящие в
заблуждение `permissions`, `concurrency`, `continue-on-error` и
`timeout-minutes`.
Сам шаг checkout выполняется action, а не shell-командой, поэтому этим
timeout не ограничен. Перед canary необходимо отдельно подтвердить
системный job timeout и cleanup policy `act_runner`.
Checkout закреплён полным commit SHA официального
[`actions/checkout` v4.3.1](https://github.com/actions/checkout/releases/tag/v4.3.1),
а `persist-credentials` выключен. До появления внутреннего mirror runner
должен иметь исходящий HTTPS-доступ к GitHub только для загрузки этого
закреплённого action. Изменение SHA требует отдельного review.
Workflow не получает application secrets, не печатает environment, не
запускает PostgreSQL, Docker, stress/soak или live Dzengi checks.
## 6. Локальный эквивалент
Один entrypoint используется человеком и workflow:
```bash
./scripts/run_ci_gate.sh quality
./scripts/run_ci_gate.sh offline-regression
./scripts/run_ci_gate.sh loopback-integration
```
Для последовательного локального запуска всех трёх режимов:
```bash
./scripts/run_ci_gate.sh all
```
Локальная проверка не требует чистого `git status`, поэтому она не мешает
разработчику с незавершёнными изменениями. Внутри чистого canary checkout
каждая job дополнительно проверяет, что тесты не создали новых файлов
репозитория.
## 7. Первый canary
Первый реальный запуск выполняется только после отдельного подтверждения:
1. провести read-only review repository diff;
2. отдельно согласовать commit и push workflow;
3. с административным доступом подтвердить фактическую версию
`act_runner`, включённость Actions и отсутствие неизвестных runners;
4. зарегистрировать изолированный runner с точным label
`dzentra-python312` и зафиксировать его image/version;
5. вручную запустить `CI Required` для принятого commit;
6. убедиться, что `quality`, `offline-regression` и
`loopback-integration` завершились успешно, не были skipped и не
остались queued;
7. проверить логи на отсутствие secrets и записать реальные status
contexts, показанные Gitea.
Только после этого canary считается зелёным. Автоматические triggers и
branch protection согласуются отдельным решением уже по фактическим status
contexts; заранее угадывать их имена нельзя.
## 8. Критерий перехода к Build 061.00
Build 061.00.0 можно начинать после одновременного выполнения условий:
- локальная матрица CI-GATE.0CI-GATE.2 зелёная;
- реальный manual canary в Gitea зелёный;
- версия и изоляция runner зафиксированы;
- пользователь отдельно подтвердил переход к production-коду.
Пока серверный canary не выполнен, корректный статус — `Canary Pending`.
## 9. Связанные источники
- [Gitea Actions quick start](https://docs.gitea.com/1.25/usage/actions/quickstart/)
- [Отличия Gitea Actions от GitHub Actions](https://docs.gitea.com/1.25/usage/actions/comparison/)
- [Gitea act_runner](https://docs.gitea.com/1.25/usage/actions/act-runner/)
- [Protected branches](https://docs.gitea.com/1.25/usage/access-control/protected-branches/)