Можно ли с помощью GitHub анализировать работу, не заглядывая в монитор сотрудника — без скриншотов и тайм-трекеров? Я Александр Кириллов, технический директор компании Evrone. Больше 20 лет я посвятил разработке. В этой статье поделюсь с вами опытом, который собрал за время работы с распределенными командами. Расскажу о том, как, не нарушая приватность разработчиков, следить за качеством работы на проектах и отслеживать нежелательные паттерны с помощью метрик в Jira и Git.  Не важно, в какой команде вы работаете — распределённой или находитесь в одном офисе — если хотите разобраться, что происходит с людьми и проектом, можно обойтись без скриншотов экранов. Есть более интересный путь — смотреть на формальные метрики в Git через инструменты аналитики кода.  Если вы спросите разработчика, что такое паттерны проектирования, думаю, большинство ответит, что это, для чего они нужны и какая в них польза. Паттерны есть не только в коде, но и в том, как он пишется.   В 2019 году мне попалась статья от компании GitPrime. На основе метаданных своих клиентов ребята попробовали выявить поведенческие паттерны индивидуальных сотрудников и команд в целом. Как результат — появился сервис аналитики, который позже купила компания PluralSight.  Мы в Evrone обратили внимание на это подход, попробовали его у себя и пришли к тому, что паттерны действительно есть, их можно отследить и тем самым сделать работу на проекте лучше, поставки кода качественнее, клиента довольнее и помочь команде в развитии. Люди пишут код, делают это в срок или в последний момент, в команде или самостоятельно, ревьюят сами себя или не дожидаясь просьбы правят код кого-то другого, исправляют ошибки или ждут, что их исправит старший коллега. А мы смотрим на данные, графики и цифры, видим общую картину и подмечаем тенденции.  С первого взгляда на аналитику из GitHub Insights довольно сложно определить, что происходит внутри проекта.  А бегло взглянув на графики, можно увидеть, когда команда отлично перформит.  Но этого мало. Чтобы оценить работу на проекте и как ведётся работа внутри, нужно больше информации, например, из метрик. Если посмотреть на Git, или на GitHub, GitLab и подобные системы более внимательно, мы увидим, что в этих системах много метаданных, с помощью которых можно следить за изменениями. Например, метрики систем контроля версий покажут: размер и частоту коммитов; даты и количество комментариев при Code Review; частоту пулл-реквестов и процесс релиза. А в таск-трекерах, Jira и похожих системах можно смотреть на метрики инструментов отслеживания задач: даты создания/закрытия задачи; привязки к веткам/коммитам из SCM. Если собирать метрики и анализировать пулл-реквесты ежедневно, это поможет выявить негативный паттерн задолго до того, как возникнет проблема.  Полезно обращать внимание на Code Churn, как метрику качества работы на проекте. Churn — показатель оттока кода. Это процент сделанной работы, которая не пошла в продакшн. К примеру, работа, написанная в стол, или та, что не принесла никакой пользы проекту за последние 22-27 дней.  Нормы Churn варьируются от проекта к проекту, и это естественная часть процесса разработки. По данным Pluralsight, если уровень оттока в проекте не выше 25% (или 75% эффективности)— это показатель большинства типичных команд разработки. Высокий Churn — признак проблем с задачей. Он может указывать на: овер-перфекционизм разработчика; проблемы коммуникаций внутри команды; сложности в интерпретации или проблемах постановки задачи. Все эти метрики важно отслеживать, чтобы не пропустить негативные тенденции и последствия в разработке проекта.  Наряду с оттоком кода есть метрики, которые предоставляют аналитические системы: «новая работа», «рефакторинг» (не обязательно legacy) и «помощь другим». Ими можно оперировать, когда надо оценить динамику изменений от спринта к спринту или в другие временные промежутки. Так становится видно, если с человеком или командой что-то не так. Мы разобрали основные метрики, а теперь поговорим о некоторых индивидуальных и групповых паттернах поведения в разработке, которые с этими метриками связаны. Я поделюсь тем, как эти паттерны распознать в поведении, в метриках, графиках и внутрикомандных процессах.  Предлагаю сразу договориться, что паттерны — не ярлыки и не характеристика человека, а поведение, которое позитивно или негативно влияет на общий результат. Названия паттернов мы придумали сами, отнеситесь к ним с иронией.  В каждой команде есть разработчик, который знает точные ответы на все вопросы. Он может полностью рассказать про какую-то часть кода или доменной логики, знает, где какой метод, что внутри модуля, и является точкой входа для большинства важных задач. Часто такие люди встречаются в открытых проектах, и обычно это ребята из core-team.  Типовые маркеры поведения Специалиста: Разработчик постоянно рефакторит один и тот же скоуп кода.  Регулярно и со стабильной частотой делает небольшие коммиты в эти участки кода. В пулл-реквестах этой доменной области как правило мало обсуждений, потому что кроме нашего специалиста мало кто понимает, как всё работает.  Если посмотреть на метрики из систем контроля версий и другие данные, можно увидеть, что Специалисты производят постоянный рефакторинг кода только в определенной части репозитория, только в определенных файлах, и не стремятся что-то менять в других.  Этот паттерн становится негативным, когда эксперт в какой-то части разработки проекта только один: отключается шеринг знаний, экспертиза концентрируется только в одном человеке и растёт Bus Factor.  С помощью автоматизированных систем С помощью систем, вроде CodeScene, в которых автоматизирован анализ поведенческих паттернов, можно разложить весь репозиторий и посмотреть, как в нём организована активность.  Эта метрика полезна не только тем, что с её помощью можно выявить потенциальные проблемы на проекте, но ещё удобно оценивать риски ухода Специалиста. Если экспертиза важных разделов проекта замкнута на нём, то можно оценить, какие части проекта просядут, если он покинет компанию, и сколько это в процентном соотношении и т.д.  Важно учитывать риски, потому что при уходе такого сотрудника вместе с ним полностью уходит экспертиза по проекту. Это значит, что придется кропотливо собирать её заново. С помощью рукописных скриптов  Если вы не хотите использовать кастомные системы или отдавать данные в облако, анализ активности в репозитории можно автоматизировать самим. Например, через скрипт, который разбирает Git-репозиторий или взаимодействует с системами контроля версий. Далее загрузить это в хранилище, собрать с помощью BI — и всё заработает, достаточно нескольких дней. Плюшкин — это разработчик, проблема которого — долгая поставка кода. Он много времени локально копит изменения и потом делает один большой коммит под конец спринта. Или может разом принести к концу недели огромный пулл-реквест.  Из-за этого обычно затягивается обсуждение архитектурного решения, отодвигается дата сдачи фичи, всего проекта или другие релизные даты, снижается качество кода и уменьшается шеринг знаний внутри компании. Плюшкин может так вести себя по разным причинам. Например, желание поделиться уже готовой работой и овер-перфекционизм, страх показаться неквалифицированным и получить критику на разных этапах работы над задачей.  Через анализ метрик — Плюшкин делает редкие, но очень крупные коммиты. Через пулл-реквесты и WorkLog в системах мониторинга. Например, когда пулл-реквесты большие и приходят в конце спринта, это сразу видно. Этот паттерн — индикатор того, что «цветочек» задачи, которую решает разработчик, никогда не принесет плодов.  Вы когда-нибудь работали с перфекционистами? Это такие специалисты, у которых всё должно быть идеально. Часто это стремление приводит к тому, что программисты продолжают возвращаться к коду, чтобы опять его переписать, ведь «он может и должен быть лучше», но результат не сильно отличается от первоначального. Активность Пустоцвета можно заметить к концу спринта. Она сопровождается повышением уровня оттока кода, нетипичным для обычных «исторических» показателей разработчика за тот же период. За этим паттерном нужно следить для того, чтобы дерево ваших задач почаще плодоносило. Снайпер — положительный паттерн. В большинстве проектов он делает хорошие атомарные коммиты с небольшим содержанием и с хорошей декомпозицией задач.  Точечные и ёмкие коммиты по задачам. Нет или мало комментариев к пулл-реквесту, Continious Integration радует зелеными тестами. Низкий Code Churn — уровень оттока не превышает нужных характеристик. Время и дата первых коммитов и мердж-реквеста — в рамках допустимых сроков. Это поведение типично для большинства команд, особенно для тех, кто построил хорошую экспертизу. И несмотря на то, что результат положительный, он часто остается без внимания тимлида на дейли-митингах, ретроспективах, встречах 1:1 — везде, где идёт общение с людьми. Рекомендую не забывать обсуждать положительный эффект от них в команде и подсвечивать хорошие результаты.  Есть сотрудники, которые с приближением дедлайна начинают тушить пожары. Заберут одну задачу, запушат, берут другую и т.д. Вроде бы всё нормально, но поведение переходит в тенденцию и повторяется от спринта к спринту, обычно ближе к релизу. Несмотря на вклад Героя в работу, у такого паттерна есть последствия: поведение команды может перерасти в привычку ожидания и развивается культура лени; ломаются процессы; есть вероятность развития синдрома самозванца у членов команды — «он всё делает, а я ничего не умею»; незаметно растёт технический долг.  Причин для спасительного поведения может быть много, но чаще это происходит, когда сотрудник не умеет делегировать, практикует  микроменеджмент и не готов делить ответственность с другими. Или есть проблема доверия на разных уровнях в команде. Чтобы делегировать задачу, нужно доверять тому, кто станет исполнителем, потому что мы делегируем не только функцию, но и ответственность за решение. Для этого важно доверять команде. Распознать паттерн удобно через анализ метрик: Растёт метрика «Помощь другим» в большинстве сервисов аналитики кода. Много «авторских» пулл- и мерж-реквестов, когда Герой сам берет задачу, сам создаёт пулл-реквест и добавляет изменения. Минимум реакции в комментариях или их отсутствие, потому что Герой не ждёт, когда кто-то посмотрит его код (если в процессах команды нет каких-то других правил на этот счёт). Уменьшается вовлечённость в процесс ревью кода, уменьшается шеринг знаний и как следствие возникают проблемы на техническом уровне по работе с архитектурой продукта. Растёт количество подобных изменений к концу спринта. Существуют вариации «Героев», когда помощи другим разработчикам на проекте слишком много и она даже избыточна. Сотрудник помогает из добрых побуждений и обычно не думает о возможных последствиях. Например, о том, что таким образом мешает развиваться другим. Представьте разработчика Васю, который сделал коммит. Он рад, сделал хорошую работу, но пришел Юра и сделал маленькое изменение — назвал переменную по-другому. Вася сделал ещё один коммит, и опять пришел Юра и переименовал название метода или добавил несколько дополнительных проверок. Это может происходить регулярно, а может эпизодически, но вот какие проблемы могут возникнуть: рефакторинг чужого кода отвлекает от собственных задач; автор оригинального коммита демотивирован и может подумать, что с ним что-то не так; автор может оказаться в зависимости от ожидания правок Помощника; увеличивается время Time To Market для задачи; подвергаются пересмотру сроки спринта. Паттерн очень похож на Героя, поэтому метрики повторяются. В отличие от Героя, Помощник сам не создаёт задачи и пулл-реквесты, он приходит в уже существующие задачи и вносит изменения. Ниже метрики, с помощью которых можно понять, что Помощник не помогает: Постоянное повторение: «коммит-правка-коммит-правка» между одними и теми же людьми. Высокий показатель «Помощь другим». Резкое снижение показателя «Вклад» (Impact) у человека, которому помогает Помощник. Помогать другим — это отличная практика и хорошая база для менторства. Я поддерживаю помощь коллегам в экспертизе, в наставничестве, но также понимаю, как сложно дать человеку самостоятельно  дойти до правильного решения, если ответ лежит на поверхности.  Скауты — адепты теории разбитых окон, но только в коде.  Представьте, что вы идёте утром по чистой улице, солнышко светит — великолепное начало дня. Перед вами на дороге лежит пустая банка колы. И не вы её туда поставили, а кто-то, но это так огорчает, что вы её поднимаете и кидаете в мусорку. Знакомо? Такое бывает и в коде: когда человек делает свою задачу, анализирует стеки, замечает, что где-то сделано неправильно и поправляет в рамках решения своей задачи.  Скаут делает работу, которую редко замечают. Но если автоматизировать аналитику, то паттерн можно распознать по следующим признакам: Высокий уровень новой работы. Высокий уровень legacy-рефакторинга по новым задачам (даже того кода, что вне контекста задачи). Но при этом: Низкий отток кода, потому что, как мы помним, он повышается, когда происходит удаление или рефакторинг кода, написанного 22-27 дней назад, а его следы давно присутствуют в нашем продукте. Количество строк кода выше прогнозируемого. Несмотря на добрые дела Скаута, это поведение считается анти-паттерном. Незаметно подчищая  код коллег, Скаут будто лишает команду возможности видеть изменения в продукте. Прячет ошибки и исправляет их, вместо того, чтобы подсвечивать, выносить в отдельные таски, маркировать как технический долг. Случается, что человек так увлекается одной задачей, что зависает над ней — пробует решить разными способами, ищет самый короткий путь и делает это большое число итераций. Его можно сравнить с физиком-практиком, который ищет идеальное решение для эксперимента и не может вовремя остановиться. Когда ваши разработчики прикидываются физиками-практиками — это повод с ними поговорить. На самом деле они могут решать не бизнес-задачу, а головоломку, и не правильными инструментами, а методом тыка. Признаки, которые выдают Застрявшего: долгое время работает над одним блоком кода; делает незначительные изменения; не понимает задачу или решаемую проблему, но пробует решить; есть пробелы в понимании кода. Объясню, в чём проблема такого паттерна. К примеру, вы увидели много коммитов: человек тут поменял, здесь поменял, тут попробовал, там ткнул. Скорее всего, он не понимает, как решить задачу или ему не хватает экспертизы. Как следствие, через несколько дней человек просто демотивируется, выходит из потока и у него опускаются руки. Чтобы не допустить этого и заранее распознать, опять обратимся к метрикам и мониторингу. Обратите внимание на величину Churn в той же части кода. Отток будет резко повышаться, потому что Застрявший только что написал код, а потом отрефакторил и удалил. Постоянный рефакторинг без обсуждений, потому что Застрявший постоянно пытается что-то сделать. Частые малоинформативные пулл-реквесты: «рефакторинг», «обновление», «fix», реакции в стиле коротких сообщений «LGTM». Можно мониторить даже размер коммита и количество изменений в одном файле. Генералист — это человек, который решает проблемы быстро, но без глубокого погружения. Он мог только прийти на проект, или его специально привлекли — такой навык бывает полезен для проекта в какой-то определенный период или для ограниченного вида задач. Генералист проходит по всему коду и делает мелкие поверхностные правки: мелкие задачи, недочёты, комментарии. В краткосрочной перспективе это отлично помогает команде быстро закрыть спринт или релиз. Но в долгосрочной перспективе у такого человека нет возможности помочь остальной команде в экспертизе по предметной области, потому что он глубоко не вникает и, по сути, ему это не нужно. Если человек привык так работать, то сложно дальше найти подходящие для него задачи.  Высокая вовлечённость в изменения по всему объёму кода. Небольшого размера коммиты, не решающие глобальных задач. Много нового кода и рефакторинга в метриках. Сравнительно меньше оттока, или даже практически нет, потому что он делает всегда что-то новое, что правит долгосрочные проблемы.  Каждый специалист — это целый мир, а каждая команда, делающая продукт — вселенная. И вселенную тоже можно анализировать через паттерны. Паттерн, который сопровождается Scope Creep — увеличением первоначально согласованного скоупа работ после их начала.  С этим сталкиваются все команды, с той разницей, что когда увеличение скоупа резкое, это можно заметить быстрее. Когда понемногу в течение всего проекта или срока — это легко пропустить.  Под конец спринта активность сильно увеличивается: например, растёт количество и размер коммитов, пулл-реквестов и их обсуждений. Из спринта в спринт поведение повторяется. Чтобы не упустить момент, когда паттерн сработает, можно предпринять вот что: Старайтесь измерять объём работ со всех сторон: не только то, что делают ваши разработчики, но и то, что вам предлагают заказчики, если вы занимаетесь заказной разработкой. Следите за необоснованным увеличением объёма работ по задаче — количество кода, пулл-реквестов и времени, которое потрачено на задачу. Если системно следить за активностью команды и количественными оценками, легче оценить динамику работы над задачами и объёмы на проектах. Как только вы заметили изменение, это повод обсудить проблему с командой. Групповой паттерн, с которым планы по оптимизации перерастают в полное переписывание.  Может возникнуть в ситуации конфликта нового кода и потребности в его рефакторинге. В метриках это видно: когда идет работа над задачей и появляется новый код, растёт и одноименная метрика в аналитике. Но если показатель нового кода резко падает и резко вырастает рефакторинг, это значит, что команда не справилась и решила всё переделать, потому что проще переписать, чем разбираться. Это может привести к негативным последствиям: в лучшем случае команда не успеет сдать задачу вовремя, в худшем — придется переписать весь проект из-за неправильно принятого решения в самом начале. Явление, когда в уже готовой работе начинается новая стадия активностей.  Вроде бы всё хорошо и согласовано, задачи сливаются в мастер-ветки, но к концу спринта или к релизу происходит возврат к уже сделанным задачам, и сильно повышается количество рефакторинг-пулл-реквестов. Причин у такого поведения может быть несколько. Например:  Пришли новые вводные от бизнеса в последний момент. Бизнес понимает, что скоро релиз, нужно получать обратную связь, а ещё хочется добавить несколько важных фич.  Команда плохо спланировала работу или в чём-то не разобралась: плохие процессы, ошибки планирования, слишком большой скоуп задач в количестве и объёме.  Если такая активность исходит от одного сотрудника, это нормально, но когда этим занимается вся команда — есть повод задать вопрос. Возможно, команде нужна помощь. Сильный всплеск количества пулл-реквестов ближе к концу спринта — обычно после утверждения основного пулл-реквеста. Рефакторинг уже сделанных задач к концу спринта. Высокий уровень метрики «New Work» в аналитических системах. Такое происходит во многих командах. Поэтому очень важно выделять скоупы в коде, директориях, файлах и мониторить уже конкретно их, если вам нужно определить какие-то точные места, где проявляется паттерн. Паттерн формальных проверок имеет яркий индикатор — крупные пулл-реквесты, в которых ожидаемо много работы для ревью, одобряются быстро и без изменений. Если время жизни пулл-реквеста экстремально короткое, значит, команда уделяет мало внимания происходящему в коде, и, скорее всего, внутри нет шеринга знаний и интереса развивать друг друга. Можно даже получить ответы, вроде: «Он и так сеньор, лучше меня знает» или «Да тут простая задача, нет смысла вникать» или «У меня своих задач по горло, некогда». В данном случае команда теряет все плюсы совместной разработки ПО: нет обмена опытом; нет возможности предвосхитить проблемы; нет условий для роста в команде: без наставничества не растёт квалификация сотрудников.  Короткий период у времени открытия и закрытия пулл-реквестов. Низкий уровень вовлечённости в процесс Code Review. Есть неявная зависимость от размера пулл-реквестов, количества комментариев и «отписок» в комментариях. Расскажу, на какие ещё паттерны можно обратить внимание в работе с командами, используя аналитику поведения кода.   Это когда, например, 2-4 сотрудника в команде делают ревью кода только друг для друга. Общаются между собой, а все остальные сами по себе. Результат — прекращается обмен знаниями внутри команды. Полезный опыт по проекту концентрируется среди нескольких сотрудников и не выходит дальше. Здесь есть риск потерять экспертизу, если эти люди покинут команду или компанию.  Если пулл-реквест висит больше недели, то велик шанс, что код в нём устарел. Его просто выкинут, а ресурсы, которые компания на него потратила, сгорят. А это не только время, но и финансы. Индивидуальный паттерн, который влияет на всю команду. Обычно такой паттерн рождается из «Специалиста» в том случае, когда кроме него никто никогда не смотрел в этот код. Почему я говорю о важности для всей команды? Если с этим человеком что-то случится (собьет автобус и человек попадет в больницу) или что более возможно — человек уйдет из команды, то быстро исправить возникшие проблемы не получится. Придётся потратить много времени и ресурсов, чтобы актуализировать экспертизу по этой части предметной области. Когда один человек отвечает за большую часть работы и замыкает на себе важные функции, то процессы, которые вокруг этого построены, коснутся каждого человека в рабочей группе. Поэтому мы и говорим о командном воздействии этого паттерна.  Критическое значение Bus Factor — это единица. Старайтесь делать так, чтобы значение было всегда больше критического. Обращайте внимание на паттерн «Специалист» и делайте соответствующие выводы. Опыт разработки учит оптимизировать всё, что можно. Когда у нас в Evrone становится много работы и данных, с которыми нужно что-то делать, мы подключаем автоматизацию, чтобы сберечь время и силы.  Автоматизировать мониторинг можно с помощью готовых сервисов или с помощью инструментов, написанных самостоятельно. Если есть возможность использовать готовые решения, то с аналитикой метрик помогут инструменты из списка: CodeClimate Velocity Waydev Pluralsight Flow (ex-GitPrime) LinearB GitClear Готовые сервисы аналитики кода помогают визуализировать процессы, работать с метриками и видеть динамику в цифрах. Но ни один из них не интерпретирует результат, не анализирует, как ведёт себя код и как он изменился. А между тем, через анализ поведения кода можно изучать поведение разработчиков — отслеживать по индикаторам, как человек проявляет себя в работе, комфортно ли ему, есть ли развитие, переработки и перегруз по задачам, как с продуктивностью и нет ли каких-то проблем с коммуникацией.   К сожалению, инструментов, которые базируются на анализе поведения разработчиков и команд, я не нашёл.  Паттерны поведения людей в работе с кодом и задачами — хорошая возможность оценить состояние команды и процессы работы.  Мы обращаем внимание на формальные показатели — метрики кода — и подмечаем тенденции. А дальше анализируем, с чем связано такое поведение и как на него повлиять.  Через метрики кода можно анализировать продуктивность людей, находить проблемы в командных процессах, ошибки управления и коммуникации и в результате получить работающий процесс, в котором людям комфортно, а в проекте меньше рисков.  Прежде, чем у вас появятся цифры, которые можно анализировать, рекомендую провести ревью того, как устроена работа над задачами в ваших спринтах и коммуникация в командах: провести ревью областей владения знаниями; узнать, как распределяются задачи и ревью; активно смотреть на код и изменения метрик; дать позитивный фидбэк на положительные паттерны; делиться своими наблюдениями на ретроспективах. Если эта тема покажется вам интересной, и у вас появятся вопросы, подписывайтесь на мои социальные сети: kirillov @evrone.com t.me/akirill0v vk.com/akirill0v github.com/akirill0v twitter.com/akirill0v Буду рад ответить и больше рассказать о своём опыте. Еще больше самых актуальных материалов будет на конференции HighLoad++ 2022 - 24 и 25 ноября в Москве. Посмотреть программу докладов и приобрести билеты можно на официальном сайте конференции.  CTO @ Evrone.com