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

02. Первый pull request

Пройди этот сценарий от начала до конца один раз, даже если изменение символическое. Цель — убедиться, что у тебя работает весь конвейер: линт → тесты → коммит → push → PR → merge.

Шаг 1. Обнови локальную копию

Зайди в клон сервис-репо, с которым будешь работать (у каждого сервиса — свой репозиторий), и обнови main:

cd <service-repo>          # например, ~/projects/user
git checkout main
git pull --ff-only

Если git pull ругается на несовпадение истории — не делай merge main на лету, разберись отдельно (скорее всего, у тебя остались локальные коммиты, не попавшие в upstream).

Шаг 2. Создай ветку

Имя ветки следует формату <type>/<short-description>:

git checkout -b feat/user-handbook-link

Префиксы: feat/, fix/, chore/, refactor/, docs/, test/. Подробнее — в conventions/commits-and-prs.md.

Шаг 3. Прогоняй тесты локально ДО правок

Ты уже в клоне сервис-репо из шага 1. Прогоняй тесты:

make test

Это baseline. Если тесты упали ещё до твоих изменений — не правь код, а иди в backend-канал выяснять, что сломано в main. Работать поверх красного main смысла нет.

Шаг 4. Внеси изменения

Правь код в редакторе. Держи изменения сфокусированными: один PR = одна логическая правка. Если по ходу ты заметил «ещё надо починить вон то» — запиши задачу отдельно, не тащи в этот же PR.

Руководствуйся правилами:

  • conventions/go-style.md — именование, обработка ошибок, контекст.
  • conventions/project-layout.md — в какую папку класть новый файл.
  • Для new-пакета / нового endpoint / новой миграции — смотри соответствующий рецепт в how-to/.

Шаг 5. Прогоняй линт и тесты

make lint
make test

Если линт ругается:

  • Читай сообщение целиком — golangci-lint даёт путь, строку и имя проверки.
  • Не выключай проверку через //nolint без комментария объяснения.
  • Типовые замечания (unused imports, shadowed err, errcheck) — это всегда правка кода, а не подавление линтера.
  • Запусти gofmt -l . — если что-то вывело, отформатируй.

Если тесты падают:

  • Запусти конкретный тест для быстрого цикла: go test -race -count=1 -run TestName ./internal/service/....
  • Добавь -v для подробного вывода.
  • Если тест зависит от Postgres/Kafka через testcontainers — убедись, что Docker запущен (docker ps не должен ругаться).
  • Зависший тест — см. troubleshooting/test-hangs.md.

Шаг 6. Покрой новый код тестами

Любое новое поведение в internal/service/ должно иметь test. Правила:

  • Новая ветка в service = минимум один happy-path тест и один error-path.
  • Новая миграция = тест, который её применяет в testcontainers-Postgres и проверяет схему.
  • Новый HTTP-endpoint = handler-тест через httptest.NewRecorder.
  • Новый Kafka-handler = тест через gochannel subscriber/publisher.

Подробнее — в conventions/testing.md.

Шаг 7. Проверь по чеклисту автора PR

Пробеги глазами checklists/pr-author.md до того, как запушишь ветку. Там собрано всё, что ревьюер спросит в первую очередь: env-файлы, миграции с advisory_xact_lock, PII в логах, обёртка ошибок через %w и т.д.

Шаг 8. Коммит

git add -p                          # добавляй интерактивно, по хункам
git status                          # убедись, что ничего лишнего
git commit -m "feat(user): add handbook link to readme"

Формат сообщения — Conventional Commits:

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

<необязательное тело с деталями>

Примеры:

feat(review): add SSE throttle for histogram updates
fix(user): close refresh-token tx on rollback
chore(media): bump pgx to v5.7.2
docs(handbook): document outbox publisher pattern

Нет --no-verify. Нет секретов в сообщении и в изменениях (проверь git diff глазами ещё раз).

Шаг 9. Push и открытие PR

git push -u origin feat/user-handbook-link

Открой PR в UI git-хостинга. Описание PR должно отвечать на три вопроса:

  1. Цель. Зачем это изменение? (1–3 строки.)
  2. Что сделано. Короткий список ключевых правок. Не пересказывай diff.
  3. Как тестировать. Команды / шаги, по которым ревьюер проверит.

Пример:

## Цель
Добавляем ссылку на handbook из README, чтобы новички быстрее находили guide.

## Что сделано
- Добавлена секция «Documentation» в README.md.
- Обновлён onboarding-текст в CONTRIBUTING.md.

## Как тестировать
- `make lint && make test`
- Открыть README в preview, убедиться, что ссылка ведёт на handbook.

Если PR трогает > 400 изменённых строк — декомпозируй на несколько. Гигантские PR плохо ревьюятся и чаще содержат баги.

Шаг 10. Code review

  • Минимум один approve. Для security-sensitive областей (auth, crypto, миграции, внешние клиенты с секретами) — два approve.
  • Отвечай на каждый комментарий. Либо правь код, либо объясняй, почему не правишь. «ok» без правки — плохой сигнал.
  • Никаких force-push после того, как ревьюер начал смотреть: пуш новые коммиты поверх. Squash произойдёт при merge.

Шаг 11. Merge

По умолчанию — squash merge. Финальное сообщение совпадает с заголовком PR, поэтому заголовок должен читаться как commit-message.

После merge:

  • Удали ветку (UI предложит кнопку).
  • У себя локально переключись на main и подтяни:
git checkout main
git pull --ff-only
git branch -d feat/user-handbook-link

Готово — ты прошёл полный цикл. Дальше всё то же самое, только быстрее.