Files
codex fd28ed2201
CI / tests-and-images (pull_request) Successful in 2m34s
Runner smoke test / runner-smoke (pull_request) Successful in 2s
Добавить risk-based Delivery First policy
2026-10-24 22:53:07 +03:00

20 KiB
Raw Permalink Blame History

Delivery First: проверка изменений по риску

Эта политика помогает быстро принимать небольшие изменения и добавляет проверки там, где ошибка затрагивает пользователей, данные или границы безопасности. Класс риска выбирает глубину проверки; он не позволяет снять обязательную проверку, одобрение или защиту main.

Порядок работы

  1. До реализации укажи в PR LOW, MEDIUM или HIGH и коротко объясни причину. Если изменение пересекает несколько областей, выбери самый высокий класс. При неопределённости используй более высокий класс.
  2. Сначала проследи путь изменения от пользовательского/API входа до данных, внешних систем и отката. Для изменения поведения добавь регрессионный тест, который подтверждает конкретный контракт или прежний дефект.
  3. Запусти проверку именно затронутого поведения и обычный Gitea CI. Для UI дополнительно выполни cd tools/frontend-visual-review && npm ci && npm test; этот браузерный набор сейчас не входит в Gitea CI.
  4. В PR перечисли класс риска, команды и результаты, остаточные ограничения, а для high-risk — совместимость, угрозы и безопасный rollback. Не заявляй проверку, которой фактически не было.
  5. Ревьюер отделяет блокирующие дефекты от улучшений. Блокер должен указывать конкретное место, условие воспроизведения и последствие. Стилистические предпочтения и предложения на будущее фиксируются отдельно и не задерживают PR.

Классы риска

Класс Когда применять Требуемое подтверждение
LOW Документация, комментарии, переименование без изменения поведения, форматирование без изменения конфигурационной семантики. Нет изменения контракта, доступа, данных или исполнения. Проверить diff и сверить утверждения/команды с исходным кодом и действующей процедурой. Выполнить обычный CI. Если документация меняет операторский шаг, проверить его в безопасном локальном или synthetic окружении.
MEDIUM Ограниченное изменение поведения одного компонента, внутреннего API, UI или локального скрипта без изменения модели доверия и формата хранимых данных. Целевые тесты затронутого компонента и регрессионная проверка, если меняется поведение; обычный CI. Для UI приложить результаты браузерного набора и synthetic визуальной проверки, если они относятся к изменённому экрану/потоку. Проверить обратную совместимость публичных запросов и ответов.
HIGH Авторизация и роли; secrets и credential flow; ingestion и происхождение данных; формат/миграция хранилища; backup/restore/recovery; production config; runner, CI и supply chain; безопасность; сетевые/host-границы; deploy и rollback. Обычный CI плюс целевые проверки каждого затронутого trust/data boundary; regression-тест; проверка негативного пути и совместимости; независимое ревью конкретных угроз и последствий. Для операций с данными использовать synthetic/staging данные и план отката. Изменение production допускается только владельцем после отдельного согласования, проверки backup и готового rollback.

Нельзя понижать класс из-за малого diff, срочности или простоты реализации: маленькое изменение правила доступа или восстановления всё равно HIGH. Нельзя считать отсутствие найденных тестов доказательством отсутствия риска.

CI и ограничения Gitea

Проверенная конфигурация проекта:

  • Репозиторий admin/akyldash, Gitea API вернул 1.25.5 2026-10-24.
  • Workflow .gitea/workflows/ci.yaml запускается на pull_request и push в main; job ID, который следует сохранять для совместимости статусов, — tests-and-images. Он последовательно выполняет backend, Telegram, backup/restore, shell guards, deployment tests, Compose/Caddy validation и две production image builds.
  • .gitea/workflows/runner-smoke.yaml сохраняет отдельный job ID runner-smoke и проверяет runtime-изоляцию job-контейнера: отсутствие системного и rootless Docker socket, production env/secrets и host checkout. Smoke дополняет статические проверки runner/CI и не дублирует их.
  • Инфраструктурная конфигурация репозитория закрепляет официальный act_runner 0.2.13, label akyldash-ci, capacity 1 и ограничения job 2 CPU, 3 GiB RAM, 512 процессов, 15 GiB store. Версия runner и лимиты приведены по IaC; в рамках этой задачи VPS не проверялся. Job-контейнеры не должны получать ни один Docker socket.
  • Текущая политика main из branch API: ветка защищена и требует одного одобрения. На момент проверки API также сообщил enable_status_check=false и пустой список status contexts. Это PR не меняет branch protection. Если владелец отдельно включит обязательные статусы, сначала проверьте их точные контексты: CI / tests-and-images (pull_request) и Runner smoke test / runner-smoke (pull_request). Не переименовывайте job IDs.

Функции и границы текущих проверок:

Блок workflow Назначение и риск пропуска Перекрытие
Checkout и Python setup Подготовка повторяемой среды; пропуск может дать ложный успех на неподходящем образе. Инфраструктурный шаг, не покрывается тестами приложения.
Backend и Telegram tests Регрессии API, логики поиска/аккаунтов и Telegram bot. Риск продуктовый; для auth/data изменений — HIGH. Разные пакеты и контракты; отдельная ветка тестов.
Backup/restore tests Целостность backup, восстановление и отказные сценарии; риск потери данных — HIGH. Не дублируется тестами backend.
Bootstrap/recovery/verifier/host-audit/production-config guards Отказ от root и защиты host identity, аргументов и production paths; обход может дать административное действие или затронуть host — HIGH. Несколько guard-тестов проверяют разные скрипты и условия; считать их дублями без анализа каждого контракта нельзя.
Runner config, installer guards и CI container isolation Ограничения runner, repeatability установки и запрет socket/privileged/host mounts; риск — доступ к host/production — HIGH. Статические/синтетические проверки дополняются реальным runtime smoke, это разные уровни.
Shell syntax и Python AST parse Раннее обнаружение ошибок парсинга; риск пропуска — поломка запуска скрипта/проверки. Это синтаксис, а не функциональные тесты.
Deployment contract/rollback tests, Compose config и Caddy validation Совместимость deploy contract/rollback и конфигурации production stack/proxy; риск — deploy outage/data impact — HIGH. Compose проверяет интерпретацию конфигурации, Caddy — синтаксис proxy, Python suite — contract/rollback logic. Функции отличаются.
Две Kaniko image builds Проверка Dockerfile и воспроизводимости backend/OpenSearch production images; риск — сломанная сборка/небезопасный путь supply chain — HIGH. Два Dockerfile — две разные целевые images; build-only, оба --no-push.
Runner smoke (отдельный workflow) Runtime-проверка известного системного socket path, production paths/secrets и host checkout отсутствия в job; риск — нарушение изоляции — HIGH. Дополняет статические runner/CI guards; не повторяет их.

Gitea API не предоставляет пригодный список steps для завершённого run в этой версии; длительность каждой строки таблицы поэтому N/A. Не распределяй общий CI runtime между блоками пропорционально числу тестов или строк кода.

Gitea 1.25 документация подтверждает используемые события push, pull_request и workflow_dispatch. Она также документирует ограничения, которые запрещают строить безопасное ускорение на привычных GitHub Actions предположениях:

  • runs-on поддерживает статическую метку или список меток; текущая akyldash-ci — статическая метка.
  • Выражения доступны ограниченно; в сравнении с GitHub Actions Gitea 1.25 обещает функцию always(), поэтому workflow не должен зависеть от if:-выражений для динамического выбора набора тестов по diff или уровню риска.
  • jobs.<job_id>.timeout-minutes, permissions, concurrency и jobs.<job_id>.environment в Gitea 1.25 игнорируются. Не используйте их как защиту, срок исполнения, обязательный approval или средство экономии.
  • У runner capacity 1. Разделение текущей последовательной работы на параллельные jobs не даёт измеримого параллельного исполнения на этом runner и может добавить запуск/очередь. Сохраняйте проверку сборки обеих production images: она подтверждает Dockerfiles, но использует Kaniko с --no-push и не публикует образы.

Источники семантики: Gitea 1.25 Actions comparison, Gitea 1.25 Actions FAQ и act_runner guide. Перед использованием новой workflow-семантики сверяй её с документацией установленной версии и проверяй фактическим run. Не добавляй проверки самой этой политики или статические тесты, утверждающие её текст.

Временные ориентиры и фактические измерения

Ориентиры — цель для поиска затрат, а не разрешение убрать тесты:

  • Обычный полный CI: до 5 минут от старта job до завершения. При превышении сначала измерить и оптимизировать узкий участок, сохраняя тесты и изоляцию.
  • Расширенный путь для HIGH (обычный CI плюс целевые проверки): целевой суммарный интервал 10–15 минут. Это пока ориентир, а не отдельный автоматический workflow или установленный timeout.

Срез 2026-10-24 получен из документированного Gitea Actions task API /repos/admin/akyldash/actions/tasks?limit=50. Взяты 20 последних завершённых tests-and-images; длительность оценена как updated_at - run_started_at:

Метрика Измерение
CI completed sample 20 прогонов, 20 success
CI median 147.5 s (2:27.5)
CI p90 172 s (2:52)
CI max 192 s (3:12)
Runner smoke median / max 2 s / 3 s, последние 20 прогонов

Прежней reconciliation или оценок длительности в доступной документации репозитория, workflows, PR и issues не найдено; этот срез является первой подтверждённой базой, и сравнить его с прежней оценкой нельзя. Все 20 измеренных полных CI прогонов ниже пяти минут; текущая конфигурация уже достигает обычного ориентира. Отдельного extended workflow нет, поэтому 10–15-минутная цель пока не имеет фактической базы. В выборке нет breakdown по steps: документированный endpoint для jobs завершённого run возвратил пустой список; это известное ограничение Gitea 1.25.5 (upstream issue #38286). Не распределяй время между тестами и image builds по предположению. При будущих изменениях workflow записывай доступные timestamps и точный размер выборки; после изменения Gitea/runner перепроверь, стал ли доступен надёжный step timing.

Метрики потока поставки

Для каждого релиза/месячного обзора отдельно собирать:

Метрика Определение и источник
Ready → merge Время с момента, когда PR реально готов к ревью, до merge. Не подменять датой создания draft PR; при отсутствии точного ready timestamp записывать N/A.
Merge → deploy Merge timestamp до фактического production deploy timestamp. Deploy пока не автоматизирован; пока нет подтверждённого deploy evidence, записывать N/A, не ноль.
CI duration run_started_at → task completion (updated_at) по Actions API; отдельно указывать медиану, p90, максимум, период и число прогонов.
Повторные прогоны Число неуспешных/повторных прогонов на commit до первого успеха; отличать rerun от нового commit/push.
Блокирующие замечания Число ревью-находок, удовлетворяющих критериям blockers выше; неблокирующие считать отдельно.
Вышедшие регрессии Подтверждённые после merge дефекты, связанные с изменением; фиксировать компонент, тяжесть и пропущенный сигнал.
Rollback Количество фактически выполненных rollback, причина и результат проверки данных/сервиса. Не считать написанный план фактическим rollback.

На момент этого аудита PR/API не дают надёжного ready timestamp для старых изменений; production deployment не автоматизирован, а задачи этого PR не содержат deploy telemetry. Поэтому ready→merge, merge→deploy, escaped regressions и rollback baseline остаются N/A, пока не появится проверяемая запись. Не придумывай значения из created_at или даты последнего update.

Критерий блокирующего ревью

Блокирующие замечания ограничены случаями:

  • воспроизводимый дефект с конкретным условием и последствием;
  • расширение доступа, утечка секрета или обход границы runner/production;
  • потеря/искажение данных или несовместимость API/storage без безопасного пути;
  • обязательный тест или подтверждение из таблицы риска отсутствует/не проходит;
  • опасная операция не имеет проверяемого backup/rollback плана.

Каждый блокер содержит файл/участок, шаги воспроизведения или точное условие, последствие и минимальный безопасный fix. Остальные замечания — отдельный неблокирующий список. Review и approval остаются за людьми; агент не начинает review сам и не сливает PR.