Довольно неожиданная даже для самого себя тематика статьи, но не поделиться не могу. Все же это про боль.
Пишу по горячим следам, так как буквально только что у меня случилась хоть и редкая, но, все же, типичная для разработки и в целом нашей сферы ситуация: сначала выяснили, что кусок функциональности невостребован, организовали работы по его удалению из кодовой базы и поддержки, но через N времени выясняется, что функциональность все-таки где-то как-то использовалась. Надо откатывать.
Делать нечего, приходится возвращать обратно и проводить регрессионное тестирование этой функциональности с последующими итеративными деплоями для соблюдения обратной совместимости. Знакомо?
Пока я возвращал нужный код в двух наших подсистемах и думал, в какой последовательности планировать релизы, осознал, что регламенты, при разработке которых я принимал непосредственное участие, работают и работают очень хорошо.
Есть в нашей базе знаний статьи, посвященные работе с git. Ну знаете, про коммиты, про сквоши и ребейзы, про именования веток, оформление мердж реквестов и так далее. С плохими и хорошими примерами, все как полагается.
Я нашел нужные коммиты и сделал откат их содержимого очень быстро, у меня CI дольше отрабатывал с автотестами, чем я вносил правки. А все благодаря двум блокам в регламентах: именование коммитов и их атомарность.
Именование
Регламентированное именование коммитов у нас исключает описания вида «fix» или «hotfix» и им
подобные — такие коммиты не несут никакой полезной смысловой нагрузки, на ревью за такое мы отрываем руки просим
переписать историю коммитов через ребейз.
Имя коммита должно четко отражать смысл изменений в нем. Из описания должно быть сразу понятно: убрано, добавлено, изменено или поправлено что-либо. При ориентировании по истории коммитов должны быть соответствующие понятные слова-триггеры, которые помогут быстро найти нужные изменения, именно этот смысл мы вкладываем в именования.
Также, все наши коммиты пишутся на русском языке. Кроме технических терминов, не имеющих аналогов, само собой. Очень, мягко говоря, тяжело читать описания, где разработчик не знает (или думает, что знает) ни правил построения предложений в английском языке, ни обладает должным словарным запасом. Из-за чего маркетинговые предложения он называет stocks, а сам коммит «add stocks orders», ну а что, переводчик ведь так сказал. А ты потом сидишь и думаешь: это добавление каких-то акций к заказам или заказов к акциям. И при чем тут вообще ценные бумаги, у нас таких в бизнесе вообще нет.
Кроме того, как мне кажется, для русскоязычной компании, где принято на психологическом уровне думать на русском языке, довольно сложно быстро ориентироваться в англоязычных текстах. Билингвы — это скорее исключение, чем правило.
Да, на ревью особо больших задач, где затрагивается множество разных мест и которые нельзя декомпозировать, не нарушая целостность и работоспособность кода, мы смотрим диффы через коммиты, а не целиком. Все мы люди и очень не любим смотреть чужой код долго, а так хотя бы внимание не рассредотачивается и появляется ощущение порционности.
Ну и, чтобы не быть голословным, вот примеры наших хороших коммитов, в которых сразу понятно, что бизнесово или технически мы тут решали и что потенциально затрагивали:
- отключен вывод для php-cs-fixer в CI;
- добавлена обработка ошибки 404 при получении розничного сертификата;
- дополнен список платежных систем банковской карты Сбербанком.
Атомарность
Атомарность же предполагает, что набор изменений, относящихся к одной задаче или ее подзадаче, будут включены в один коммит. И нет, это вообще не значит, что если задача охватывает множество разных мест, все эти места должны быть ровно в одном коммите. Это значит, что один коммит должен быть самодостаточным. В нем не должно быть лишнего.
Если задача предполагает обновление пакетной зависимости и при этом в нем предусматривается неломающая ничего обратная совместимость, такое обновление должно уйти в отдельный атомарный коммит. Это позволяет потом отделить этот коммит через cherry-pick в отдельный же мердж реквест и протолкнуть перед целевой задачей, чтобы это обновление уже было доступно всем разработчикам и какому-нибудь следящему за своевременным обновлением боту renovate.
По примерам именования коммитов выше должно быть уже понятно, что здесь подразумевается. Коммит дополнения списка платежных систем может подразумевать изменения, затрагиваемые в эндпоинте, его openapi-документации, доменном enum платежных систем и расширении доменных юзкейсов доменного заказа, включая модульные тесты. Само собой, если по субъективной оценке исполнителя изменений много, даже мой пример можно разбить на несколько коммитов поменьше.
Послесловие
Работа разработчиком — это не только написание кода. Культура разработки — это не только про то, как мы этот код пишем. Культура разработки — это огромный пласт коллективно проработанных и формализованных требований, начиная от того, как именно и куда мы кладем создаваемый код и тесты, какие именно функции пригодности мы используем в проектах и как следим за энтропией, заканчивая тем, как именно устроен жизненный цикл задачи, включая уровни проектирования, конструирования, тестирования и передачи этой самой задачи в эксплуатацию после деплоя.
Культурой разработки мы вводим не столько бюрократические процессы, хотя они также имеют место, сколько стараемся упростить всем жизнь. Где-то можно ускориться за счет строгого продуманного регламента, лучше не пренебрегать этими возможностями.
А благодаря тому, что у нас в регламентированных именованиях также есть специальный префикс-маркер с номером задачи, это также позволило понять, когда мы сломали и в каком релизе это улетело на прод.
Я очень рад, что то, что мы потом и кровью прорабатывали, итеративно корректировали, работает на нас. Надеюсь, у вас так же!