Найти тему

Как не пропустить невалидный код в репозиторий

Оглавление
Статья подготовлена для студентов курса «C# ASP.NET Core Developer» в образовательном проекте OTUS.

Когда в твоей команде работает больше одного человека, так или иначе все сталкиваются с проблемой разных стилей кодирования каждого члена команды. Кто-то пишет скобки для блоков if...else, кто-то нет. Когда проект становится больше, то такой код труднее читать и еще сложнее проводить код-ревью.

Чтобы код-ревью и прочие командные митинги не превратились в обсуждение tab vs spaces на повышенных тонах, лучше настроить репозиторий таким образом, чтобы сам проект не допускал написание невалидного и нестандартного для команды кода.

С одной стороны, использование разных стилей кодирования может показаться вкусовщиной, недостойной внимания. Ну не оборачивает джун единственную строку кода после условия if, а кто-то пишет, что с того? Если оставить код из под пера джуна "как есть", то это может стать "бомбой замедленного действия": ту строку кода после if могут удалить, и тогда под условие попадет следующая строка. Конечно, эта ситуация обычно отлавливается на код-ревью, однако бывает так, что этот потенциальный баг проходит проверку, и вот две основных причины:

  • Мы все люди, а люди ошибаются.
  • Люди социальны, а значит, вступать "в очередной раз" в конфликт, связанный со стилями, не захочется. И тут возможны два варианта:

a) "Лучше поправлю сам", думает проверяющий, и правит код; b) проверяющий срывается на джуна и высказывает свои сомнения в его адекватности и необходимости существования.

Как можно добиться того, чтобы каждый писал в соответствии с командным стилем? Бить по рукам на код-ревью каждый раз демотивирует и автора кода, и самого проверяющего. К счастью, эта проблема будоражит умы не одного программиста не первый год, и в нашем распоряжении сейчас есть множество инструментов.

Цель этой статьи — рассказать другим и себе будущему, как я настраиваю репозиторий проекта таким образом, чтобы он сам обезопасил себя от невалидного кода с точки зрения стандартов команды.

Что мы имеем

В качестве примера возьмем демонстрационный проект, код которого будет выложен на GitHub. Так как я занимаюсь разработкой на .NET Core, то и проект будет написан на нем. Что я буду использовать:

  • .NET Core 3.1;
  • Angular 8+;
  • Github-аккаунт;
  • Travis CI.

Я уже создал демонстрационный репозиторий проекта и настроил в нем Travis-CI. Далее в статье разберем, что необходимо было сделать для этого и почему.

Пайплайн репозитория

Пайплайн репозитория — механизм, предотвращающий попадание невалидного кода со второстепенных веток в основную master branch.

"Из коробки" пайплайны доступны в Gitlab и Azure DevOps, а в Github — через Travis CI.

Настраиваем репозиторий

Мне нравится подход к разработке софта Егора Бугаенко. Я законспектировал несколько его докладов в своем блоге. Если кратко, то вот основные принципы, которым я следую при настройке репозитория:

  • Ограничение прав на пуш. Я ограничиваю права на пуш в develop и master всем, кроме мейнтейнеров (maintainer).
  • Пайплайн сборки. Я прописываю пайплайн для сборки проекта в CICD и прогона юниттестов как для бэкенда, так и фронта.
  • Repository is a king. В репозитории я прописываю правила работы с кодом и gitflow, а также другие связанные с подходами в разработке документы.
  • Fail fast. Если код написан невалидно с точки зрения стандартного стиля, то разработчик получит ошибку компиляции.
  • Git pre-commits hoocks. Чтобы не занимать агенты CI гитлаба лишком часто, я добавляю прогон тестов и иные полезные операции на прекоммит хуки гита.

Что мы получаем в итоге? Во-первых, в master и develop смогут залить код только мейнтейнеры проекта. В идеале, конечно, и им нужно ограничить доступ, чтобы только "автомат" мог сливать ветки. Я оставил реализацию этого принципа "на потом". Ограничение прав настраивается через интерфейс гитлаба, поэтому я не буду описывать этот этап здесь.

Валидация бэкенда

Я настраиваю solution-файл (*.sln) проекта так, чтобы он выдавал несоответствия написанного кода стандартам стайл-гайда .NET как ошибки компиляции. Чтобы сделать это, мне понадобится файл с перечислением кодов ошибок, пара nuget-пакетов и немного терпения.

Я использую stylecop в проектах для .NET Core. Чтобы его верно настроить, прежде всего мы создаем несколько файлов в корне проекта рядом с solution-файлом (ссылки ведут на gist.github.com):

После этих действий наш проект не будет собираться, пока в нем будут ошибки стиля кодирования.

Валидация фронтенда

Фронтенд-приложение тоже необходимо валидировать. Здесь настройки пайплайна менее критичны к нарушениям стиля кода: если мы пропустим где-то точку с запятой, то проект все равно будет работать. На страже репозитория здесь будет стоять агент пайплайна. Я автоматизирую следующие команды:

-2

Есть небольшой нюанс работы агентов репозитория с тестами. Дело в том, что для прогона тестов необходим движок Хрома (Chrome / Chromium), а он чаще всего отсутствует в контейнерах CI-систем. Чтобы агент мог запускать тесты фронта, я добавляю npm-пакет puppeteer в проект, который подтянет с собой и хромиум.

Таким образом, чтобы и корректность фронтенда валидировалась пайплайном, нам необходимо проделать следующие шаги:

1.Добавить новую команду "test-headless-ci-only": "ng test --browsers ChromiumNoSandbox" в блок scripts файла packages.json:

-3

2.Установить пакет npm install puppeteer и прописать его в файле karma.conf.js в самое начало файла:

-4

3.Добавить кастомный лаунчер тестов в файле karma.conf.js в секцию customLaunchers:

-5

Теперь в скриптах пайплайна можно запускать тесты командой npm run est-headless-ci-only.

Стандартизируем код фронтенда

Чтобы код-ревью тикетов для фронтенда не превратились в обсуждение предпочтений форматирования, лучше всего стандартизировать его. Я пользуюсь инструментом prettierrc, потому что репозиторий проекта имеет много звезд и документация написана подробно. Эта библиотека помогает подкорректировать форматирование автоматически. Чтобы добавить prettierrc в проект, необходимо:

1.Установить пакеты prettier и pretty-quick глобально:

-6

2.Добавить файл конфигурации с именем .prettierrc в корень фронтенд-приложения:

-7

3.Добавить список файлов для игнорирования prettier-ом в файл с именем .prettierignore в корень фронтенд-приложения:

-8

Теперь можно "привести в порядок" код фронтенда командой pretty-quick --staged.

Использование прекоммит-хуков

Запуск агента пайплайна в CI/CD системах — это потребление ресурсов, и, зачастую, небесплатных. Можно и нужно запускать валидацию проекта локально, но делать это на каждый коммит надоедает. В итоге люди перестают запускать скрипты так часто. Чтобы автоматизировать этот процесс, я пользуюсь прекоммит-хуками, которые позволяют запускать полезные скрипты при коммитах и пушах.

Для фронтенда лучше всего подойдет библиотека husky. Чтобы настроить хук, необходимо:

1.Установить библиотеку husky

-9

2.Добавить хук husk в файл package.json в конец:

-10

Здесь я разделил команды: нет необходимости проверять тесты фронтенда на каждый коммит, но мы не дадим залить изменения в удаленный репозиторий, пока тесты не будут "зелеными".

Итог

После того, как сделаны описанные в статье шаги, я получаю проект, который "защищает сам себя" от невалидного кода. Понятное дело, что одной проверкой синтаксиса и стайл-гайда не уберечь продукт от багов, однако даже эти незначительные вещи помогают в достижении большего качества кода и позволяют обсуждать архитектурные решения на код-ревью, а не вопросы форматирования.

Какие возможности раскрывает ASP.NET Core перед C#-разработчиком? Расскажем об этом 3 ноября на вебинаре в формате интервью с Алексейм Ягуром. Алексей поделится карьерными инсайтами и представит программу онлайн-курса «C# ASP.NET Core Developer». Вы узнаете, почему на курсе практика проходит в командах, какие навыки позволят вам создавать полноценные web-сервисы и получите ответы на все вопросы по образовательному процессу.
Чтобы лучше подготовиться к встрече, пройдите вступительный тест, который покажет сложность курса именно для вас.