bot: Коммит — сообщение, Push, конфликты, публикация #9

Closed
opened 2026-10-12 19:33:32 +03:00 by Eleboba · 2 comments
Owner

Описание

Требования C-20…C-25 из SPEC §4.1, Publisher — ARCHITECTURE §2.3.

Желаемый результат

  • «💬 Сообщение коммита» (1–200 символов, первая строка ≤ 72); «🚀 Push» активна при непустом черновике и сообщении; сводка + подтверждение.
  • Один коммит в main от бота с трейлером Telegram-User: @user (id); ответ с sha и ссылкой ≤ 10 с, запись в pushes.
  • Конфликт с base_sha по тем же путям → «перезаписать»/«отменить».
  • Очередь из одного воркера, pull --rebase при отказе push (до 3 раз).
  • Лимит 20 пушей/час на участника.

Подзадачи

  • app/repo/publisher.py
  • Применение черновика к рабочему дереву
  • Экран подтверждения и обработка конфликта
  • Лимитер пушей
  • Тесты на bare-репозитории: коммит, конфликт, гонка двух пушей, лимит

Анализ

Затрагиваемые файлы

Файл Что меняется
app/repo/publisher.py новый
app/bot/routers/commit.py push
docker-compose.yml volume клона и ключа

Ограничения и риски

Ключ монтируется read-only. После успешного пуша черновик очищается только после подтверждения push от remote.

Как проверить

Два участника пушат одновременно в разные файлы — два коммита; в один файл — второму предложен конфликт.


Лог выполнения

2026-10-13

  • Задача переписана под SPEC v2 (QR-доступ, меню из 4 разделов, командная модель — ADR-011…013).

2026-10-15

  • app/repo/publisher.py: lock (пуши по одному) → fetch → конфликт = пути черновика ∩ git diff base_sha origin/main → checkout -B/reset --hard/clean → применить черновик (удаление чистит опустевшие папки; путь вне клона → отказ) → add -A → пусто? → коммит от tgit-bot с трейлером Telegram-User: @user (id) → push; отказ → fetch + rebase, до 3 раз; конфликт при rebase → CONFLICT. Лимит 20 пушей/час по таблице pushes.
  • UI: на экране черновика «💬 Сообщение коммита» и «🚀 Push» (только при изменениях и сообщении) → подтверждение со сводкой → «⏳ Пушу…» → «✅ Запушено: sha — сообщение» + ссылка (GIT_COMMIT_URL_TEMPLATE, пока пусто) + «⏳ CI…». Конфликт → список файлов и «Перезаписать».
  • pushes хранит chat_id/message_id сообщения о пуше — #11 будет обновлять его статусом CI/CD.
  • Тесты: 8 новых на настоящем bare-репозитории — трейлер и автор, add/modify/delete, «нечего коммитить», конфликт → перезапись, независимое изменение в main не конфликт, отклонённый push → rebase (хук «кто-то запушил раньше»), ../ отклонён, лимит; плюс полный сценарий через бота до коммита в удалённом репозитории. Всего 136, покрытие 91 %.
## Описание Требования C-20…C-25 из [SPEC](https://gitea.24studbank.ru/HSE/tgit/src/branch/dev/docs/SPEC.md) §4.1, Publisher — [ARCHITECTURE](https://gitea.24studbank.ru/HSE/tgit/src/branch/dev/docs/ARCHITECTURE.md) §2.3. ## Желаемый результат - «💬 Сообщение коммита» (1–200 символов, первая строка ≤ 72); «🚀 Push» активна при непустом черновике и сообщении; сводка + подтверждение. - Один коммит в `main` от бота с трейлером `Telegram-User: @user (id)`; ответ с sha и ссылкой ≤ 10 с, запись в `pushes`. - Конфликт с `base_sha` по тем же путям → «перезаписать»/«отменить». - Очередь из одного воркера, `pull --rebase` при отказе push (до 3 раз). - Лимит 20 пушей/час на участника. ## Подзадачи - [x] `app/repo/publisher.py` - [x] Применение черновика к рабочему дереву - [x] Экран подтверждения и обработка конфликта - [x] Лимитер пушей - [x] Тесты на bare-репозитории: коммит, конфликт, гонка двух пушей, лимит ## Анализ ### Затрагиваемые файлы | Файл | Что меняется | |------|--------------| | `app/repo/publisher.py` | новый | | `app/bot/routers/commit.py` | push | | `docker-compose.yml` | volume клона и ключа | ### Ограничения и риски Ключ монтируется read-only. После успешного пуша черновик очищается только после подтверждения push от remote. ## Как проверить Два участника пушат одновременно в разные файлы — два коммита; в один файл — второму предложен конфликт. --- ## Лог выполнения ### 2026-10-13 - Задача переписана под SPEC v2 (QR-доступ, меню из 4 разделов, командная модель — ADR-011…013). ### 2026-10-15 - `app/repo/publisher.py`: lock (пуши по одному) → `fetch` → конфликт = пути черновика ∩ `git diff base_sha origin/main` → `checkout -B/reset --hard/clean` → применить черновик (удаление чистит опустевшие папки; путь вне клона → отказ) → `add -A` → пусто? → коммит от `tgit-bot` с трейлером `Telegram-User: @user (id)` → `push`; отказ → `fetch` + `rebase`, до 3 раз; конфликт при rebase → `CONFLICT`. Лимит 20 пушей/час по таблице `pushes`. - UI: на экране черновика «💬 Сообщение коммита» и «🚀 Push» (только при изменениях и сообщении) → подтверждение со сводкой → «⏳ Пушу…» → «✅ Запушено: sha — сообщение» + ссылка (`GIT_COMMIT_URL_TEMPLATE`, пока пусто) + «⏳ CI…». Конфликт → список файлов и «Перезаписать». - `pushes` хранит `chat_id`/`message_id` сообщения о пуше — #11 будет обновлять его статусом CI/CD. - Тесты: 8 новых на настоящем bare-репозитории — трейлер и автор, add/modify/delete, «нечего коммитить», конфликт → перезапись, независимое изменение в main не конфликт, **отклонённый push → rebase** (хук «кто-то запушил раньше»), `../` отклонён, лимит; плюс полный сценарий через бота до коммита в удалённом репозитории. Всего 136, покрытие 91 %.
Eleboba added this to the M1 · MVP: загрузка → коммит → CI milestone 2026-10-12 19:33:32 +03:00
Eleboba added the botfeaturesize/1 labels 2026-10-12 19:33:32 +03:00
Eleboba self-assigned this 2026-10-12 19:33:32 +03:00
Eleboba added a new dependency 2026-10-12 19:40:21 +03:00
Eleboba changed title from bot: GitPublisher — коммит загрузок в tgit-uploads to bot: Коммит — сообщение, Push, конфликты, публикация 2026-10-13 22:53:12 +03:00
Author
Owner

Зависимость от #7 снята: репозиторий загрузок и ключ бота работают на Gitea (ADR-015), CI — Gitea Actions (ADR-016). #7 остаётся открытой только под SourceCraft.

Зависимость от #7 снята: репозиторий загрузок и ключ бота работают на Gitea (ADR-015), CI — Gitea Actions (ADR-016). #7 остаётся открытой только под SourceCraft.
Author
Owner

Смержено в dev через PR #38 — закрываю.

Смержено в `dev` через PR #38 — закрываю.
Sign in to join this conversation.