Гитхаб в Академии
В HTML Academy почти все работают с GitHub. Доступ есть у каждого сотрудника, и, кажется, только бухгалтер пока им не пользуется. Репозиториев уже больше 50, а в команде 19 человек. Код открыт внутри компании: нет отдельной части, которую одна группа прячет от другой.
При таком количестве проектов недостаточно договориться, что мы пользуемся одним сервисом. Нужно ещё понимать, что лежит в каждом репозитории, кто отвечает за задачу и когда изменения можно принимать. Эти правила мы обсуждали с командой после ретроспективы. Часть уже работает, часть мы только начинаем пробовать в 2017 году.
Репозиторий должен объяснять, что в нём находится
Когда проектов много, описание становится рабочим инструментом. У репозитория должно быть понятно назначение. Если есть сайт, нужна ссылка на него. Для запуска необходима инструкция: что установить, какую команду выполнить, какие особые требования учесть.
Коллега не должен сначала разбирать исходники, чтобы догадаться, как запустить приложение. В одном проекте Node.js и Gulp, в другом PHP; знания о привычном проекте не заменяют описание соседнего.
С доступом ко всему коду мы заодно договорились о границе: непосредственно в master изменения не отправляем. Для работы есть отдельные ветки. Новая возможность получает имя с feature/, исправление ошибки — ветку, связанную с номером задачи.
Мы не стали придумывать подробную классификацию. Если изменение не исправляет ошибку, относим его к новой возможности. Это соглашение об именовании, которое помогает ориентироваться среди веток.
master защищён от принудительной перезаписи истории и удаления. Изменения принимаем через пулреквесты. Конечно, остаются люди с правами обойти ограничение: наш генеральный директор Саша иногда может отправить код прямо в основную ветку. Поэтому одной настройки недостаточно, нужно ещё договориться ею пользоваться.
За задачу отвечает один человек
У задач мы заметили две противоположные проблемы. В одной не назначен никто. В другой ответственных столько, что непонятно, с кого спрашивать результат. Мне оба варианта не подходят.
Я не верю в ответственность, разделённую между всеми сразу. У каждой задачи должен быть один ответственный. Остальные могут помогать, обсуждать и писать код, но нужен человек, который доведёт её до результата.
Несколько ответственных часто появляются потому, что хочется позвать людей в обсуждение. Для этого в GitHub есть упоминания. Можно обратиться к конкретному человеку или целой команде.
Мы создали внутренние команды по интересам: например, людей, которым небезразличны семантика или русский язык. В них может вступить любой сотрудник, которому интересна тема. Когда в обсуждении нужна помощь, достаточно упомянуть команду, и участники получат уведомление. При этом ответственность за исходную задачу никуда не перемещается.
Назначение ответственного у нас связано с ролями, которые сложились в команде. Отдельного инструмента, который автоматически вычисляет нагрузку и выбирает исполнителя, мы не используем. Это остаётся частью договорённостей между людьми.
Одинаковые метки во всех проектах
Для задач и пулреквестов у нас общая система меток. Часть обозначает область работы: курсы, интенсивы или оплата. Другие показывают состояние задачи, её тип и срочность.
Тип помогает отличить ошибку от улучшения или запроса новой возможности. Статус отвечает на вопрос, что происходит сейчас: работа ещё идёт, требуется проверка или наступил другой этап. Для срочности достаточно отмечать крайние случаи — важные и неважные. Всё остальное остаётся обычным приоритетом.
Есть и редко используемые метки, объясняющие, почему задача закрыта. Мы не пытаемся превратить каждое решение в длинную переписку, если достаточно обозначить известную причину.
Статусы и метки назначаем вручную. Отдельной доски поверх GitHub у нас нет. Иногда человек забывает обновить статус, но мы пока решаем это внутри команды, а не добавляем ещё один инструмент, который будет принуждать к каждому переходу.
Сами наборы меток создаются автоматически. На уровне организации есть обработчик создания репозитория: он удаляет стандартные метки GitHub, добавляет наши и включает защиту master. Новый проект сразу получает те же правила, что и остальные.
Это нужно не только для порядка внутри одного репозитория. GitHub позволяет искать задачи и пулреквесты сразу по всей организации. Если метки одинаковы, можно собрать все назначенные на меня задачи или всё, что ожидает проверки, независимо от проекта. Пятьдесят разных наборов названий такую возможность почти уничтожили бы.
Один коммит — одна небольшая задача
Мы стараемся делать изменения атомарными. У коммита должна быть одна конкретная небольшая задача, которую можно понять и при необходимости отменить отдельно от остальных.
На словах с этим согласны почти все, но в работе изменения смешиваются: начал исправлять ошибку, попутно переставил код, потом обновил что-нибудь ещё. В истории получается большой кусок, который неудобно разбирать и откатывать. Поэтому к этому соглашению приходится возвращаться.
В приватных проектах сообщения пишем по-русски: вся команда русскоязычная. В открытых репозиториях используем английский, потому что с кодом могут работать и другие люди.
Для сообщения выбрали вопрос «что делает этот коммит?». Например: «Обновляет описание Академии». Мы описываем действие изменения в настоящем времени. Когда история оформлена одинаково, её легче читать: видно, что и в какой последовательности поменялось.
Если изменение связано с задачей, добавляем её номер. Для завершённой задачи можно использовать поддерживаемые GitHub слова вроде fixes или closes, чтобы она закрылась после принятия изменений в основную ветку.
Раньше мы дописывали такую ссылку в конце сообщения без отделения. Потом увидели предложение Гарри Робертса заключать служебную часть в квадратные скобки. Мне понравилось: основной текст визуально отделяется от номера задачи. Команда согласилась попробовать.
Спор о том, кто «исправляет»
Форма сообщения вызвала отдельную дискуссию. Один из участников возразил: изменение делает человек, а коммит — запись в Git. По его мнению, «исправил опечатку» звучит человечнее и лучше выражает ответственность автора, чем «исправляет опечатку».
Я смотрю на это как на описание того, что произойдёт при применении изменения. Автор при этом никуда не исчезает: он указан в истории. Но это наша внутренняя договорённость, которую мы только начали проверять в работе. На учеников мы её не переносим.
В русском «обновляет» не является повелительным наклонением. Мы выбираем форму, которую нам удобно читать. Пока она мне нравится значительно больше неопределённого «small fixes».
Пулреквест нужен до окончания работы
Разработчики часто не хотят показывать незавершённый код. Кажется, что сначала надо всё доделать, убрать шероховатости и только потом отправлять коллегам. Мне хочется видеть работу раньше.
Мы договорились открывать пулреквест как можно скорее, даже если пока изменился только README. Незаконченную работу помечаем WIP, work in progress. Коллегам понятно, что это ещё не просьба принять готовое решение, но уже можно посмотреть направление и обсудить его.
Описание пишем по-русски. Если пулреквест должен закрыть несколько частей задачи, перечисляем их с флажками. Так видно, что уже выполнено и что ещё осталось. У пулреквеста, как и у задачи, должны быть метки и один ответственный.
Ссылки с командами закрытия не означают, что задача исчезнет сразу после очередного коммита в рабочую ветку. Она закрывается, когда изменения принимаются в основную ветку. Тогда же мы получаем уведомления о завершении в Slack.
Проверка кода и место для обсуждения
Каждый пулреквест должен пройти ревью. Когда код готов к проверке, мы ставим status: needs review и приглашаем коллег посмотреть изменения.
В GitHub появился встроенный механизм запроса ревью. Теперь можно выбрать проверяющих, и они получат уведомления. По результату человек может одобрить изменения, запросить исправления или оставить комментарий без такого решения.
Я отдельно прошу команду комментировать изменения всего пулреквеста. Комментарий к отдельному коммиту выглядит почти так же, но в обсуждении работы его легче потерять. Труднее вернуться к нему и понять, исправлено ли замечание. Когда разговор остаётся в пулреквесте, он связан с тем набором изменений, который мы собираемся принимать.
На встрече возник вопрос: если за задачу отвечает один человек, почему проверяющих может быть несколько? Каждый ведь способен решить, что посмотрят остальные. Более того, ожидание нескольких людей увеличивает время до публикации.
Такая проблема действительно относится к процессу. Необходимые проверки можно сделать условием слияния, но само ограничение не заставит человека вовремя открыть код. Команде нужно договориться, кто должен проверить изменение, и разбираться, если работа застревает. При переходе на новые правила потребуется время, чтобы они стали привычными.
Как не потеряться в уведомлениях
Я советую коллегам подписываться на важные для них репозитории и обсуждения. При этом доступ ко всему коду не означает обязанности читать каждое событие во всех проектах. Нужны фильтры, корректные метки и понятное назначение ответственности.
Общая система меток уже позволяет собрать задачи по всей организации. Накануне доклада появилась и недостающая часть интерфейса запросов ревью: общий список пулреквестов, в которых ждут моей проверки. До этого искать такие приглашения часто приходилось в почте.
Теперь можно открыть список и последовательно посмотреть, что ожидает внимания. Но кто-то всё равно должен правильно назначить проверку и обновить состояние работы. Инструмент помогает видеть договорённости, а поддерживаем их мы сами.
Что ещё предстоит автоматизировать
У нас подключён платный Travis для приватных репозиториев, но тесты пока есть лишь в нескольких проектах. Конфигурации линтеров тоже подготовлены, однако автоматический запуск ещё не устроен повсюду.
Следующий шаг — подключить автоматический линтинг во всех репозиториях и запретить слияние, если обязательная проверка не прошла. Для части проектов хотим настроить автоматическую публикацию. Это планы, которые должны дополнить уже существующие ветки и ревью.
И отдельно я прошу команду изучать Git. Интерфейс GitHub помогает поставить задачу и обсудить код, но понимание истории, веток и изменений всё равно нужно человеку, который с ними работает.