Уведомления и ревью
Самый распространённый шум в работе разработчика — не алерты и не логи, а поток уведомлений: комментарии к ревью, упоминания, изменения в задачах, результаты сборок. Эта глава о том, как освободить ревью от того, что может проверить машина, и как организовать уведомления, чтобы важное не терялось.
Ревью как канал сигнала
Код-ревью существует, чтобы обсуждать то, что может оценить только человек: правильность решения, понятность, архитектурные последствия, пропущенные случаи. Каждый комментарий про отступы, порядок импортов или лишний пробел в конце строки отнимает внимание у этих вопросов — и у автора, и у рецензента. Хуже того, такие комментарии создают ощущение проделанной работы: двадцать замечаний выглядят как тщательное ревью, даже если ни одно из них не касается сути.
Отсюда правило, сформулированное во вводной главе: всё, что можно проверить автоматически, должно проверяться автоматически и до того, как изменение увидит человек.
Автоформатирование
Споры о стиле кода прекращаются в тот момент, когда стиль определяет программа, а не человек. Автоформатер переписывает код в единый вид, и обсуждать становится нечего. Важно не то, какой именно стиль выбран, а то, что он один и применяется без исключений.
Базовые настройки редактора стоит зафиксировать в корне проекта в файле .editorconfig — его понимают почти все редакторы и среды разработки без дополнительных расширений:
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4
[*.{yml,yaml,json}]
indent_size = 2
[Makefile]
indent_style = tabВнедрять форматер в существующий проект лучше одним отдельным изменением, которое переформатирует всё сразу и ничего больше не меняет. Такое изменение легко проверить и легко исключить из истории авторства строк: большинство систем контроля версий позволяют указать список коммитов, которые нужно пропускать при просмотре авторства.
Линтеры
Линтер находит не стиль, а вероятные ошибки: неиспользуемые переменные, недостижимый код, сравнение с None через равенство, изменяемые значения по умолчанию в аргументах функций. Но линтер тоже может шуметь. Включённые «на всякий случай» все правила подряд дают сотни предупреждений, которые разработчики учатся подавлять, не читая.
- Начинайте с небольшого набора правил, которые ловят настоящие ошибки, и расширяйте его постепенно.
- Каждое правило либо блокирует слияние, либо выключено. Предупреждения, которые ни на что не влияют, никто не исправляет.
- Подавление правила в конкретной строке сопровождается кратким объяснением причины.
Хуки pre-commit
Чем раньше обнаружена проблема, тем дешевле её исправить. Проверка на машине разработчика до коммита занимает секунды; та же проверка в CI — минуты и лишний цикл «отправил — дождался — исправил — отправил снова». Фреймворк pre-commit позволяет описать набор хуков в одном файле и одинаково запускать их локально и в CI:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-merge-conflict
- id: check-added-large-files
args: ["--maxkb=500"]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.4
hooks:
- id: ruff
args: ["--fix"]
- id: ruff-formatХуки локально легко обойти, поэтому те же проверки обязательно запускаются в CI — первым и самым быстрым заданием:
lint:
stage: .pre
image: python:3.12-slim
variables:
PRE_COMMIT_HOME: "$CI_PROJECT_DIR/.cache/pre-commit"
cache:
key:
files: [.pre-commit-config.yaml]
paths: [.cache/pre-commit]
script:
- apt-get update -qq && apt-get install -y -qq git
- pip install -q pre-commit
- pre-commit run --all-files --show-diff-on-failureКеш окружений хуков с ключом по файлу конфигурации делает повторные запуски быстрыми. Версии хуков в rev закреплены, а обновляются осознанно, отдельным изменением, иначе новая версия линтера может внезапно покраснить все открытые изменения.
Настройка уведомлений
Системы контроля версий, трекеры задач и CI по умолчанию уведомляют обо всём. Настройки по умолчанию рассчитаны на то, чтобы пользователь ничего не пропустил, а не на то, чтобы он мог работать. Несколько приёмов, которые помогают почти везде:
- Подписка по участию. Уведомления приходят только по задачам и изменениям, где вы автор, рецензент или упомянуты, а не по всему проекту.
- Автоматическое назначение рецензентов по файлу владельцев кода. Запрос приходит тем, кто отвечает за изменённую часть, а не всей команде.
- Результаты CI — только о своих изменениях и только о падениях. Уведомление об успешной сборке не несёт информации: успех — ожидаемое состояние.
- Разные каналы для разной срочности. Вызов дежурного — через систему оповещения, запрос ревью — через систему контроля версий, обсуждения — в чате. Смешивание всего в одном месте гарантирует, что срочное утонет.
Дайджесты вместо потока
Многие уведомления важны, но не срочны: новая версия зависимости, изменение в документации соседней команды, еженедельная статистика нестабильных тестов. Для них поток отдельных сообщений — худший формат. Каждое сообщение прерывает, а вместе они всё равно не читаются.
Дайджест собирает такие события за период и доставляет одним сообщением в предсказуемое время: например, по понедельникам утром. Хороший дайджест короткий, сгруппирован по смыслу и начинается с того, что требует решения. Если в дайджесте нечего сообщить, его лучше не отправлять вовсе, чем отправлять пустой.
Если уведомление какого-то типа вы стабильно отмечаете прочитанным, не открывая, это шум. Отключите его или переведите в дайджест. Раз в квартал полезно пересматривать все подписки — их число со временем только растёт.
Типичные ошибки
- Ревью стиля руками. Любое замечание, которое повторяется больше двух раз, — кандидат в правило линтера или форматера.
- Упоминание всей команды. Сообщение, адресованное всем, не адресовано никому. Лучше назвать одного ответственного.
- Уведомления об успехе. Сообщения «сборка прошла», «задача обновлена», «проверка завершена» создают фон, на котором теряются сообщения о проблемах.
- Одновременное включение новых правил линтера. Сотня новых предупреждений в один день приводит к массовому подавлению. Новые правила включаются по одному, вместе с исправлением существующих нарушений.
Итог
- Ревью — для того, что может оценить только человек. Стиль и формализуемые ошибки проверяет машина.
- Автоформатер снимает споры о стиле; внедряется одним отдельным изменением.
- Линтер начинается с малого набора правил; каждое правило либо блокирует, либо выключено.
- Хуки pre-commit дают быструю обратную связь локально, те же проверки обязательны в CI.
- Уведомления — по участию, о падениях, а не об успехах; несрочное — в дайджест.