Разработка: ветки, код-ревью, стандарты и Definition of Done
На собеседовании вас спросят про алгоритмы. На работе 80% времени вы будете заниматься другим: читать чужой код, выяснять, что имелось в виду в задаче, ждать CI, объяснять в комментариях к PR, почему вы сделали именно так, и переделывать после ревью.
Исследования подтверждают ощущение: разработчики тратят на понимание существующего кода примерно 58% рабочего времени — это данные Xin Xia и соавторов, «Measuring Program Comprehension: A Large-Scale Field Study with Professionals» (IEEE TSE, 2018, препринт). Написание нового кода — далеко не самая объёмная часть работы.
Поэтому этап «разработка» в SDLC — это не «сесть и накодить». Это конвейер с чёткими правилами: как задача попадает к вам, где вы её делаете, кто и как проверяет результат, что автоматически проверяет робот и в какой момент можно честно сказать «готово». Разберём весь конвейер.
Если вы ещё не читали, откуда берутся задачи, — начните с Требования и аналитика и Проектирование. Здесь мы стартуем с момента, когда задача уже лежит в трекере и на ней ваше имя.
Единица работы — не строка кода, а изменение, доехавшее до пользователя
Первое, что ломает мышление вчерашнего студента: код, который «работает у меня локально», не имеет ценности. Ноль. Ценность появляется, когда изменение прошло ревью, слилось в основную ветку, проехало через тесты, попало в релиз и не сломало продакшн.
Из этого следует практическое правило, которое отличает джуна от мидла: джун оптимизирует скорость написания кода, мидл оптимизирует скорость прохождения кода через весь конвейер. Написать за час фичу, которая потом три дня висит на ревью из-за размера, — это медленнее, чем писать её полтора дня и вливать по кусочкам.
Метрика, которую отслеживают зрелые команды, называется lead time for changes — время от первого коммита до работающего в проде изменения. Она входит в четвёрку DORA-метрик (dora.dev/guides/dora-metrics-four-keys), и почти всё, о чём эта статья, влияет именно на неё.
Жизненный цикл задачи: что означают колонки в трекере
Статусы в Jira/YouTrack/Linear выглядят как бюрократия, пока не поймёшь, что это протокол синхронизации. Колонка отвечает на вопрос «кто сейчас должен что-то сделать и чего ждёт задача».
Что здесь важно понять честно:
- Точный набор колонок у каждой команды свой. В стартапе бывает три статуса, в банке — двенадцать, включая «На согласовании ИБ» и «Ожидает окна релиза». Ни то ни другое не «правильно»: количество статусов отражает количество реальных передач ответственности между людьми.
- Возвраты назад — норма, а не позор. Стрелки
Review → In ProgressиTesting → In Progressсрабатывают постоянно. Плохо не то, что задача вернулась, а то, что она возвращается по одной и той же причине пятый раз подряд. - Blocked — самый недооценённый статус. Джуны боятся его ставить, потому что кажется, будто это признание в беспомощности. На самом деле незаявленный блокер — это дни простоя, о которых никто не знает. Правило: если вы застряли дольше, чем на 60–90 минут, и не сдвинулись, вы обязаны об этом сказать.
- Восемь задач в «In Progress» у одного человека — это ноль сделанных задач. Про WIP-лимиты и почему поток важнее загрузки подробно в треке project-management; здесь достаточно запомнить, что переключение контекста стоит дороже, чем кажется.
Что сделать до того, как открыть редактор
Пять минут здесь экономят два дня потом:
- Прочитать задачу целиком, включая комментарии — там часто спрятано «мы передумали».
- Найти критерии приёмки. Если их нет — сходить к автору задачи и получить их текстом в тикете. Не в личке, не голосом: текстом в тикете, потому что через месяц спор о том, что имелось в виду, разрешать будет нечем.
- Посмотреть, кто последний трогал этот код (
git log -p --follow <файл>,git blame) — это ваш будущий ревьюер и источник контекста. - Прикинуть размер. Если задача разваливается на 800 строк изменений — резать на части до начала работы, а не после.
- Уточнить нефункциональные ожидания: нагрузка, обратная совместимость API, миграция данных. Это то, что джуны забывают, а на ревью потом всплывает как «а ты подумал про старых клиентов?».
Ветки: как несколько человек пишут в один репозиторий
Ветка в Git — это не «копия проекта», а всего лишь подвижный указатель на коммит. Именно поэтому создать ветку стоит наносекунды, а слить две сильно разошедшиеся ветки — иногда день.
Две базовых философии
Trunk-based development. Одна главная ветка, ветки живут часы или максимум пару дней, всё сливается в trunk постоянно, незаконченные фичи прячутся за feature flags. Каноническое описание — trunkbaseddevelopment.com. Это подход команд, которые деплоят несколько раз в день.
GitFlow. Долгоживущие ветки develop, release/*, hotfix/*, feature/*, релиз собирается
из отдельной release-ветки. Автор модели Vincent Driessen в 2010 году описал её в посте
«A successful Git branching model»,
и десять лет спустя добавил туда честное примечание: если вы делаете веб-приложение с непрерывной
поставкой, вам, скорее всего, нужен не GitFlow, а что-то попроще. Читать это примечание —
обязательно, потому что половина команд тащит GitFlow по инерции.
GitHub Flow — компромисс: только main и короткие ветки под задачу, merge через pull request,
деплой из main. Это то, что вы, вероятнее всего, встретите на первой работе.
Как выбирают на практике
| Условие | Скорее trunk-based / GitHub Flow | Скорее GitFlow / release-ветки |
|---|---|---|
| Частота релизов | несколько раз в день | раз в 2 недели и реже |
| Кому поставляем | своему SaaS | коробка, мобильные сторы, on-premise у клиента |
| Нужно ли поддерживать старые версии | нет | да, 1.4 и 1.5 одновременно живут у разных клиентов |
| Есть ли регламент релизного окна | нет | да, релиз согласуют с ИБ, ЦОД, бизнесом |
| Зрелость автотестов | высокая, CI ловит регресс | ручной регресс на стенде занимает неделю |
Мобильная разработка почти всегда ближе к release-веткам просто потому, что ревью в App Store занимает время и откатить релиз мгновенно нельзя. Банковский монолит с релизом раз в месяц — тоже. Это не отсталость, это следствие цены ошибки. Подробнее контраст разобран в Энтерпрайз изнутри и Стартап изнутри.
Почему долгие ветки — это дорого
Стоимость слияния растёт нелинейно от времени жизни ветки. За три недели в main успевает
приехать рефакторинг, переименование модулей и обновление библиотеки — и ваш идеальный код
конфликтует со всем сразу. Хуже конфликта только семантический конфликт: Git слил файлы
без единого маркера <<<<<<<, всё собралось, а логика сломалась, потому что коллега поменял
контракт функции, которую вы вызываете.
Практика, которая спасает: git fetch && git rebase origin/main (или merge из main) хотя бы раз
в день. Разбирать конфликт из одного дня расхождения — 10 минут. Из трёх недель — рабочий день
и высокая вероятность, что вы что-то потеряете при разрешении.
Feature flags: как вливать незаконченное
Классический ответ на «фича готова только наполовину, но я не хочу держать ветку»: влить код в main, но выключить его флагом.
// Флаг читается из конфигурации/сервиса фич-флагов на каждом запросе,
// а не один раз при старте — иначе выключить его в инциденте можно
// будет только перезапуском сервиса.
if flags.Enabled(ctx, "checkout.new_pricing", user) {
return newPricing(ctx, cart)
}
return legacyPricing(ctx, cart)
Плюсы очевидны: маленькие PR, непрерывная интеграция, возможность включить фичу на 5% пользователей и мгновенно выключить при инциденте (это уже про релиз и эксплуатацию).
Честная цена: каждый флаг — это ветвление логики, то есть удвоение числа состояний системы и тестовых сценариев. Флаги обязаны иметь владельца и дату удаления, иначе через год у вас двести мёртвых флагов, и никто не знает, что будет, если тронуть любой из них. Хорошее описание техники и её издержек — у Мартина Фаулера, «Feature Toggles».
Гигиена коммитов и веток
- Имя ветки содержит ключ задачи:
feature/AB-142-checkout-discounts. Автоматика в трекере связывает ветку с тикетом, а через полгода вgit logпонятно, зачем это делалось. - Сообщение коммита объясняет «зачем», а не «что» — «что» видно в диффе. Плохо:
fix. Хорошо:fix(checkout): не применять скидку дважды при повторной отправке формы. Формат из примера — Conventional Commits, на нём часто строится автогенерация changelog и версионирование. Классика жанра про сообщения — «How to Write a Git Commit Message». - Rebase против merge — тема священных войн. Практический минимум: не переписывайте историю
ветки, которую кто-то уже забрал себе;
git push --force-with-leaseвместо--force; в общую ветку force-push не делают никогда. Часто команда просто включает squash merge — тогда вся ветка становится одним коммитом в main и спор исчезает. - Секреты в репозитории. Закоммиченный токен считается скомпрометированным навсегда, даже если вы удалили его следующим коммитом: он остался в истории и в чужих клонах. Правильная реакция — сразу отозвать ключ, а не пытаться «почистить». Для профилактики ставят gitleaks или аналог в CI.
Код-ревью: главный обучающий механизм в команде
Зачем это делают на самом деле
Ловля багов — не главная цель, хотя она и работает. Основное — это:
- распространение знаний: после ревью код знают минимум два человека, bus factor растёт;
- читаемость: код пишут один раз, читают сто, и ревью — единственный момент, когда «непонятно» можно сказать вовремя;
- соответствие принятым решениям: архитектурным договорённостям, ADR, стандартам;
- обучение: для джуна ревью — это персональный курс от команды, самый быстрый канал роста;
- разделённая ответственность: после апрува это уже не «твой код», а код команды.
Самое полезное чтение по теме — работа Google «Modern Code Review: A Case Study at Google» (Sadowski et al., ICSE-SEIP 2018, research.google/pubs/pub47025): там честно показано, что основная польза ревью в масштабе — образовательная и нормативная, а не «поиск дефектов». Практическая часть, которую стоит прочитать целиком, — открытый Google Engineering Practices / Code Review.
Размер PR решает всё
Внимание ревьюера — исчерпаемый ресурс. На 50 строках человек читает каждую. На 1500 строках он листает, ищет что-нибудь очевидное, не находит и ставит апрув — это называется rubber stamping, и это худший вид ревью: он создаёт иллюзию проверки. Практическая эвристика большинства инженерных руководств — держаться в районе двух-трёх сотен строк изменений на PR и разбивать большее на серию.
Как резать большую задачу:
- Сначала отдельным PR — рефакторинг без изменения поведения (его читать легко).
- Потом — миграция схемы БД, обратно совместимая, без использования новых полей.
- Потом — новая логика за выключенным флагом.
- Потом — включение флага и удаление старой ветки кода.
Да, это четыре PR вместо одного и четыре круга ревью. И это всё равно быстрее, чем один разговор на неделю вокруг простыни в 1200 строк.
Как автору не бесить ревьюера
- Сделайте self-review. Откройте свой же дифф в интерфейсе PR и прочитайте как чужой.
Половина замечаний ловится здесь: забытый
console.log, закомментированный код, случайно переформатированный файл. - Напишите описание. Не «делает то, что в задаче». Что менялось, почему выбран этот подход, какие альтернативы отброшены, как это проверить руками, что осталось за скобками. Хорошее описание PR экономит ревьюеру полчаса разбирательств.
- Не смешивайте. Функциональное изменение + переформатирование всего файла = дифф, в котором ничего не видно. Форматирование отдельным коммитом или отдельным PR.
- Отвечайте на каждый комментарий. Либо правкой, либо аргументом, либо «согласен, вынес в отдельную задачу AB-157». Молча закрыть тред — верный способ поссориться.
- Не воспринимайте замечания как оценку личности. Это единственный по-настоящему сложный навык из списка, и он тренируется только практикой.
Как ревьюеру не быть узким местом
Скорость важнее глубины. PR, лежащий сутки, — это сутки простоя автора и растущий дрейф ветки. Нормальная договорённость: первый ответ в течение нескольких часов рабочего дня, даже если это «посмотрю после обеда, вот беглые мысли». В Google-руководстве прямо написано: если вы не можете посмотреть внимательно сейчас — дайте хотя бы быстрый отклик.
Помечайте уровень замечания. Это одна из самых дешёвых и самых полезных практик:
blocking:— так мержить нельзя (утечка данных, гонка, сломанная обратная совместимость);question:— я не понял, объясните, возможно, всё в порядке;suggestion:— было бы лучше вот так, но решать вам;nit:— придирка по вкусу, не блокирует.
Без такой маркировки автор не понимает, что обязательно, а что вкусовщина, и либо переделывает всё подряд, либо игнорирует важное.
Комментируйте код, а не человека. Разница не в вежливости ради вежливости, а в том, что формулировка определяет, будет ли обсуждение продуктивным.
| Плохо | Хорошо |
|---|---|
| «Ты опять не подумал про конкурентность» | «Если два запроса придут одновременно, здесь возможна двойная запись — стоит взять блокировку или уникальный индекс» |
| «Перепиши это нормально» | «Функция делает три вещи сразу; если вынести валидацию отдельно, её можно будет протестировать без БД» |
| «Так не пишут» | «У нас в проекте принято возвращать ошибку, а не паниковать — см. internal/errors/README.md» |
| «Зачем ты это сделал?» | «question: почему здесь мапа, а не слайс? Может, я упускаю сценарий» |
Не превращайте ревью в дедовщину. Симптомы, при которых процесс сломан: ревьюер требует переписать по своему вкусу без аргумента; замечания приходят порциями по одному в день; джуну возвращают PR восемь раз подряд с новыми претензиями. Если спор зашёл в тупик — правило простое: обсуждение переезжает в голосовой звонок на 10 минут, а итог записывается в тред PR текстом. Тексты в комментариях плохо передают тон, и половина конфликтов на ревью — это конфликт интонации, а не техники.
Кто ревьюит. В зрелых репозиториях есть файл CODEOWNERS: он автоматически назначает
владельцев конкретных каталогов. Обязательный апрув владельца критичного модуля — нормальная
практика; требование двух апрувов на всё подряд обычно означает, что процесс не доверяет людям
и просто удваивает задержку.
Когда ревью — не лучший инструмент
Ревью асинхронно, а значит, у него есть задержка. Иногда дешевле:
- парное программирование для сложной или незнакомой области — ревью происходит в реальном времени, отдельный PR-ревью потом можно сделать формальным;
- разговор до написания кода — обсудить подход на 15 минут, чтобы не выяснять на ревью, что вся структура выбрана неверно (это, по сути, продолжение проектирования);
- прототип на выброс, который никто не ревьюит, потому что он будет удалён.
Стандарты кода: спор, который нужно автоматизировать
Правило номер один: если о правиле можно спорить, но его можно проверить машиной — пусть проверяет машина. Спор о табах, кавычках и порядке импортов не создаёт ценности, зато прекрасно портит отношения.
Слои автоматических проверок
Ключевая мысль диаграммы: человек включается последним и смотрит только то, что машина проверить не может — правильность решения, читаемость замысла, соответствие требованиям.
Из чего это состоит на практике
- Форматтер — не обсуждается и не настраивается:
gofmt,prettier,black/ruff format,dotnet format,mix format. Go в этом смысле выиграл спор радикально: формат один на всю экосистему. - Линтер и статический анализ —
golangci-lint,eslint,ruff, аналайзеры Roslyn,credo. Ловят реальные классы ошибок: неиспользуемое, затенённые переменные, потерянные ошибки, подозрительные приведения типов. - Типы — строгий режим TypeScript, mypy/pyright, nullable reference types в C#. Самый дешёвый способ убрать целый класс замечаний с ревью.
- Тесты и покрытие — подробно в следующей статье трека.
- Проверка зависимостей —
npm audit,govulncheck, Dependabot/Renovate. - Соглашения о коммитах и PR — commitlint, шаблон описания PR в
.github/pull_request_template.md.
Минимальный, но честный пример пайплайна:
# .github/workflows/ci.yml — то, что должно быть в любом репозитории с первого дня
name: CI
on:
pull_request:
push:
branches: [main]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.23"
# Форматирование: не «замечание на ревью», а падение сборки
- name: Проверка форматирования
run: test -z "$(gofmt -l .)"
- name: Линтеры
uses: golangci/golangci-lint-action@v6
# -race ловит гонки, которые на ревью глазами не находят почти никогда
- name: Тесты
run: go test -race -coverprofile=coverage.out ./...
- name: Известные уязвимости в зависимостях
run: go run golang.org/x/vuln/cmd/govulncheck@latest ./...
Про pre-commit хуки честно. Они удобны, но на них нельзя строить гарантии: хук живёт
на машине разработчика, его можно не установить и обойти через --no-verify. Хук — это про
быстрый отклик, CI — про гарантию. Нужны оба, но источник истины один: CI.
Как жить со стандартами в легаси
Включить строгий линтер на проекте с историей в семь лет — значит получить 40 000 замечаний и заблокировать команду. Работающий подход:
- Зафиксировать baseline: текущие нарушения записываются в файл исключений и не считаются
ошибкой (
golangci-lintсnew-from-rev,eslintс--cache,ruffс# noqaпо списку). - Новые и изменённые файлы проверяются строго. Правило «boy scout rule»: тронул файл — оставил чуть чище.
- Постепенно выпиливать исключения отдельными задачами в рамках работы с техническим долгом.
Хорошие открытые ориентиры по стилю, если своего гайда нет: Google Style Guides, Go Code Review Comments, Effective Go.
Definition of Done: договор о слове «готово»
Классический диалог на дейли:
— Задача готова? — Да, код написан. — А тесты? — Ну, тестов нет. — А на стенде проверял? — Нет, локально работает.
Definition of Done — это письменное соглашение команды, которое делает такой диалог невозможным. Термин пришёл из Scrum (см. Scrum Guide и трек scrum-master), но полезен в любом процессе, включая канбан и «у нас нет процесса».
Не путайте три разные вещи:
| Что | Про что | Кто владеет | Пример |
|---|---|---|---|
| Definition of Ready | когда задачу можно брать в работу | команда + аналитик/PO | есть критерии приёмки, оценка, нет неизвестных блокеров |
| Acceptance criteria | что именно должна делать эта задача | автор задачи | «при повторной отправке формы скидка не применяется дважды» |
| Definition of Done | качественная планка для любой задачи | команда | тесты, ревью, документация, мониторинг |
Критерии приёмки уникальны для задачи, DoD одинаков для всех задач. Их регулярно путают, и тогда в DoD пытаются писать функциональные требования.
Как выглядит рабочий DoD
Реальный пример DoD небольшой продуктовой команды — восемь пунктов, которые помещаются в закреплённое сообщение в чате:
Задача считается Done, если:
1. Код слит в main, ветка удалена.
2. CI зелёный: сборка, линтеры, юнит- и интеграционные тесты.
3. PR апрувнут минимум одним человеком, не автором; для платежей — владельцем модуля.
4. Новая логика покрыта тестами; на исправленный баг есть тест, падавший до фикса.
5. Проверено на staging по критериям приёмки из задачи.
6. Обновлены: миграции, конфиги, README/ADR, если менялись контракты.
7. Добавлены метрика и лог, по которым можно понять, что фича работает в проде.
8. Тикет переведён в нужный статус, в комментарии — что и как проверять.
Антипаттерны DoD
- DoD как декларация. Написали на воркшопе, повесили в Confluence, никогда не открывали. DoD живёт только если он встроен в чеклист PR и/или в правила CI.
- DoD из тридцати пунктов. Никто не читает. Лучше семь выполняемых, чем тридцать игнорируемых.
- DoD, спущенный сверху. Планку качества, в которую команда не верит, команда обойдёт. Это соглашение, а не приказ; менеджер может настаивать на наличии DoD, но не диктовать его.
- «Done-done». Если в команде появились градации «сделано» и «сделано по-настоящему», — значит, DoD не работает и его надо переписать под реальность.
- DoD, игнорирующий эксплуатацию. Самый частый пропуск у команд без дежурств: нет пунктов про логи, метрики и алерты — а потом в проде фича молча не работает три недели.
DoD должен эволюционировать. Появились дежурства — добавили пункт про алерты. Появился внешний API — добавили пункт про версионирование контракта. Ревизия на ретроспективе раз в квартал — хороший ритм.
Кто с кем взаимодействует на этапе разработки
Честная поправка: этой схемы целиком у вас может не быть. В маленькой команде нет отдельного тестировщика — тогда его роль исполняют автотесты плюс перекрёстная проверка коллегой, и пункт «проверил на стенде» в DoD становится критичным. В большом энтерпрайзе, наоборот, между разработчиком и продом появятся ещё согласование ИБ, ревью архитектурного комитета и релизное окно. Кто за что отвечает в разных конфигурациях — в статье Кто есть кто в команде.
Жизненный цикл бага: почему он отличается от задачи
Три вещи, которые отличают работу с багом от работы с фичей:
- Сначала воспроизведение, потом код. «Кажется, я понял, в чём дело» без воспроизведения — это лотерея. Не воспроизвели — не сможете доказать, что починили.
- Тест, падающий до фикса. Это единственная гарантия, что вы починили именно то и что оно не вернётся. Если тест зелёный и до вашей правки — вы чинили не то.
- Severity ≠ priority. Severity — насколько страшно техническое последствие. Priority — насколько срочно бизнесу. Опечатка на главной странице лендинга имеет низкий severity и высокий priority. Падение фоновой джобы, о которой никто не знает, — наоборот.
Энтерпрайз и стартап: одна и та же работа, разные настройки
| Аспект | Крупная компания | Стартап / небольшая команда |
|---|---|---|
| Ветвление | release-ветки, окна релизов, иногда монорепо со сложными правилами | trunk-based, деплой из main по мержу |
| Ревью | обязательно, часто 2+ апрува, CODEOWNERS, регламент SLA | обязательно, но 1 апрув; иногда «после факта» на мелочах |
| Стандарты | общекорпоративный гайд, платформенная команда, готовые шаблоны CI | что успели настроить; часто линтера нет, и это ваша возможность его принести |
| DoD | формализован, привязан к аудиту, есть обязательные согласования | договорённость в чате, меняется на ходу |
| Скорость | изменение до прода — недели | часы |
| Что вы получаете | масштаб, сложные системы, культура процесса, наставники | широта задач, влияние на продукт, скорость обратной связи |
| Чего лишаетесь | скорости и ощущения влияния | страховки: некому подсказать, легко закрепить плохие привычки |
Ни одна колонка не «правильнее». Для первой работы важнее не тип компании, а наличие людей, которые будут читать ваш код и объяснять замечания. Один вдумчивый ревьюер даёт больше роста за полгода, чем два года самостоятельного написания кода без обратной связи. Как это влияет на грейд — в статье Грейды.
Типичные ошибки на этапе разработки
Список составлен из того, что реально всплывает на ревью у начинающих:
- Начать кодить, не поняв задачу. Два дня работы в мусор, потому что имелось в виду другое.
- Молча застрять. Полтора дня на проблеме, которую коллега решил бы за пять минут. Правильная форма вопроса: что делаю, что пробовал, что ожидал, что получил.
- Огромный PR. «Заодно отрефакторил» — самая дорогая фраза в код-ревью.
- Отсутствие тестов «потому что некогда». Работает ровно до первого регресса, после которого выясняется, что времени ушло больше.
- Спор о вкусовщине на ревью. Стиль автоматизируют, а не обсуждают.
- Игнор комментариев ревьюера. Молча закрытый тред читается как неуважение.
- Коммит секретов,
.envи артефактов сборки. Проверьте.gitignoreдо первого коммита. - Локальная правка прямо в main. Даже если «на минутку».
- Правка бага без воспроизведения. Вы не знаете, починили ли вы что-нибудь.
- «Готово» без проверки на стенде. Локальное окружение отличается от тестового всегда.
- Забытые логи и метрики. В проде фича молча не работает, и узнаете вы об этом от клиента.
- Долгоживущая ветка «пока не доделаю». Возвращаемся к картинке с дрейфом.
Мини-итог
- Работа на этапе разработки — это конвейер от тикета до прода, и оптимизировать надо скорость всего конвейера, а не скорость набора кода.
- Ветки должны быть короткими; долгая ветка платит нелинейно растущим налогом на слияние. Незаконченное вливают за feature flag, а флаги обязаны иметь владельца и срок жизни.
- Стратегия ветвления вытекает из частоты релизов и цены ошибки, а не из моды.
- Код-ревью — прежде всего механизм распространения знаний. Держите PR маленькими, помечайте уровень замечаний, комментируйте код, а не человека, и отвечайте быстро.
- Всё, что может проверить машина, должна проверять машина: форматтер, линтер, типы, тесты, аудит зависимостей — в CI, а не в комментариях к PR.
- Definition of Done — командное соглашение из 5–8 выполнимых пунктов, включающее эксплуатацию (логи, метрики), а не только «код написан».
- Баг требует воспроизведения и падающего теста; severity и priority — разные вещи.
Что почитать
- Google Engineering Practices: Code Review — лучшее бесплатное руководство по ревью с обеих сторон.
- Sadowski et al. «Modern Code Review: A Case Study at Google» (ICSE-SEIP 2018).
- Trunk Based Development и «A successful Git branching model» с примечанием автора — два полюса спора о ветках.
- Martin Fowler, «Feature Toggles» и «Continuous Integration».
- Pro Git — бесплатная книга, главы 3 и 7 обязательны.
- Nicole Forsgren, Jez Humble, Gene Kim, «Accelerate» — про связь инженерных практик с результатом бизнеса; краткая версия — dora.dev.
- Conventional Commits и «How to Write a Git Commit Message».
- Scrum Guide — первоисточник про Definition of Done.
Что дальше
Мы довели изменение до слияния в main и договорились, что считать сделанным. Теперь разберёмся, как это изменение проверяют: какие бывают уровни тестов, что из этого пишет сам разработчик, как выглядит приёмка и что делать, когда тестировщика в команде нет.