Перейти к содержанию

Коммиты и pull request'ы

Единые правила для веток, коммитов и ревью. Применяются ко всем репозиториям команды.

Ветки

Имена

Формат — <type>/<kebab-short-description>:

feat/review-sse-throttle
fix/user-refresh-token-rollback
chore/bump-pgx
refactor/media-upload-session-state
docs/handbook-events-section
test/notification-retry-backoff

Префиксы:

Префикс Когда Примеры
feat/ Новая функциональность feat/media-thumbnail-worker
fix/ Исправление бага fix/user-session-leak
chore/ Не меняет поведение (bump зависимостей, CI, конфиг) chore/bump-go-1-22
refactor/ Реорганизация кода без изменения поведения refactor/extract-outbox-pkg
docs/ Только документация docs/handbook-logging
test/ Только тесты / test infra test/review-handler-tables

Правила: - Только нижний регистр и дефисы. Никаких подчёркиваний и camelCase. - Короткое описание — 2–5 слов. Не пиши туда номер тикета. - Одна ветка = один PR = одна логическая правка.

Коммиты

Conventional Commits

Каждый commit-message — Conventional Commit:

<type>(<scope>): <imperative summary>

<optional body>

<optional footer>

Примеры:

feat(review): add SSE throttle for histogram updates

Throttle prevents bursty updates when a place gets many reviews at once.
Default limit is 5 events/sec per place.

---

fix(user): close refresh-token tx on rollback

The previous version leaked a pgx connection when refresh failed mid-tx.

---

chore(deps): bump pgx to v5.7.2

---

docs(handbook): document outbox publisher pattern
  • type — те же, что и для веток: feat, fix, chore, refactor, docs, test, плюс perf (оптимизация без изменения API) и ci (изменения CI).
  • scope — сервис или подсистема: user, review, media, notification, handbook, deps, ci.
  • Summary — императив в настоящем времени, нижний регистр, без точки в конце: add, fix, update, не added, fixes, updated.
  • Длина summary — до 72 символов.

Тело коммита

Если изменение неочевидно — опиши почему, а не что. Diff расскажет, что.

Плохо:

fix(user): change method

Хорошо:

fix(user): invalidate guard cache on password change

Without invalidation, a freshly-changed password left the old cached
token-version in Redis for ~60s, so stale tokens continued to pass.

Размер коммита

  • Один коммит = одна логическая правка. Не мешай рефакторинг и bug-fix в одном коммите.
  • Автоматические правки (gofmt, go mod tidy) — отдельным коммитом.
  • Ребейзь/squash локально до того, как откроешь PR, если вышла каша.

Pull Request

Размер

  • Цель — ≤ 400 изменённых строк. Это не считая сгенерированных файлов (swagger, mock'и).
  • Больше 400 — сначала подумай, можно ли разбить. Чаще всего можно: отдельный PR на интерфейс, отдельный на реализацию, отдельный на подключение в main.go.
  • Если PR не бьётся — опиши в описании, почему единый PR неизбежен (например, миграция схемы + код в одной точке). Ревьюеры будут смотреть внимательнее.

Описание

Обязательный шаблон:

## Цель
Одним абзацем: зачем это изменение?

## Что сделано
- Ключевые правки списком. Не пересказывай diff построчно.
- Упоминай новые файлы, новые env-переменные, новые миграции.

## Как тестировать
- `make lint && make test`
- Конкретные команды / curl / шаги, по которым ревьюер проверит.

## Риски / совместимость
(Опционально) — если задеваются миграции, публичные API, формат событий.

Примеры того, что писать в «Риски»:

  • «Добавлена новая миграция 005. Rolling-deploy безопасен: колонка nullable, старый код её игнорирует.»
  • «Формат события review.created расширен полем place_name (optional). Schema-Version остаётся 1, consumer'ы не ломаются.»

Ревью

Правила:

  1. Минимум один approve для merge.
  2. Два approve для security-sensitive областей:
  3. аутентификация / авторизация (в репозитории сервиса user — файл internal/service/auth.go, middleware auth),
  4. крипто (подписание JWT, хеширование паролей, шифрование данных),
  5. новые миграции,
  6. изменения в outbox/events (риск потерь сообщений),
  7. любой код, который трогает секреты / токены / OAuth-конфигурацию.
  8. Автор не merge'ит без approve. Даже если reviewer промолчал сутки — пингуй, не merge'ь сам.

Как ревьюить:

  • Смотри сначала описание PR. Если оно непонятное — проси автора уточнить до того, как начнёшь читать код.
  • Проверяй по checklists/pr-reviewer.md.
  • Комментарий «вопрос» vs «блокер» помечай явно. Префиксы nit:, question:, blocker: экономят всем время.
  • Approve при остатках nit — допустимо, если автор их точно увидит.

Как отвечать на комментарии:

  • На каждый комментарий — либо правка, либо ответ, почему не правишь.
  • ok без правки — бесполезный ответ. Пиши, что сделал: «исправил в commit abcdef».
  • Разногласия разрешаются в комментариях, а не в чате (чтобы осталось в истории ревью).

Merge

  • Squash merge — дефолт. История main линейная, один PR = один commit.
  • Финальное сообщение squash-а — заголовок PR. Поэтому заголовок PR — сразу в формате commit-message: feat(review): add SSE throttle ...
  • После merge — удали ветку.
  • Force-push в ветку PR — запрещён после того, как reviewer начал смотреть. До первого ревью — можно. Во время/после — только новые коммиты.
  • Force-push в main — запрещён всегда.

Правила по hooks и безопасности

  • Никогда git commit --no-verify. Если hook падает — чини проблему, а не подавляй проверку.
  • Никаких секретов в коммитах. Проверяй git diff глазами перед push'ем. Если случайно закоммитил секрет:
  • Немедленно отзови секрет (сгенерируй новый, обнови в .env.example как placeholder).
  • Напиши в backend-канал.
  • Не надейся, что git rebase -i удалит секрет из истории — он уже в remote.
  • .env в .gitignore. Только .env.example коммитится, и он содержит placeholders, не реальные значения.
  • Не коммить сгенерированные бинари, bin/, dist/, .idea/, .vscode/. Проверь .gitignore перед первым PR в новый сервис.

Что не делать

  • Не мержи PR с красным CI, даже если ты уверен, что это «flaky test». Flaky тест — отдельный issue, сначала чини/карантинируй его.
  • Не пиши «drive-by» правки вне scope PR. Нашёл баг в соседнем файле — делай отдельный PR.
  • Не добавляй в PR правку «заодно я ещё вот это переименовал» без упоминания в описании. Незаявленные правки — повод для re-request changes.