<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Emil Yangirov</title><subtitle>Рефлексирующий разработчик</subtitle><author><name>Emil Yangirov</name></author><id>https://teletype.in/atom/yangirov</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/yangirov?offset=0"></link><link rel="alternate" type="text/html" href="https://blog.yangirov.ru/?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=yangirov"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/yangirov?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-05-06T11:11:22.920Z</updated><entry><id>yangirov:sonarqube</id><link rel="alternate" type="text/html" href="https://blog.yangirov.ru/sonarqube?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=yangirov"></link><title>SonarQube – попытка обуздать техдолг?</title><published>2024-04-04T14:21:08.158Z</published><updated>2024-04-04T16:36:59.192Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/45/b0/45b028fd-ea2b-485a-afb5-24bd582d2015.png"></media:thumbnail><category term="it" label="IT"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/fb/9b/fb9b2dee-32fa-4e58-8d60-c54d27b815b4.png&quot;&gt;Что такое SonarQube, как настроить и как он может помочь в контроле технического долга.</summary><content type="html">
  &lt;h2 id=&quot;Km5i&quot;&gt;Мотивация&lt;/h2&gt;
  &lt;p id=&quot;QZQx&quot;&gt;Большой продукт сложен в поддержке и сколько разработчиков не бери, всё равно качество кода будет страдать.&lt;/p&gt;
  &lt;p id=&quot;KmME&quot;&gt;&lt;strong&gt;Причины:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;WO5Z&quot;&gt;
    &lt;li id=&quot;PhYr&quot;&gt;сроки&lt;/li&gt;
    &lt;li id=&quot;9MqJ&quot;&gt;отсутствие тестов&lt;/li&gt;
    &lt;li id=&quot;JgJn&quot;&gt;поверхностное код-ревью&lt;/li&gt;
    &lt;li id=&quot;DtD6&quot;&gt;&lt;strong&gt;отсутствие контроля техдолга&lt;/strong&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;DbtC&quot;&gt;&lt;em&gt;Технический долг&lt;/em&gt; - это как невыплаченный кредит: когда разработчики берут &amp;quot;заем&amp;quot; времени, выбирая быстрые и простые решения для достижения цели, но забывают вернуть его обратно, оставляя за собой задолженность в виде неоптимизированного кода. &lt;/p&gt;
  &lt;p id=&quot;Gc1p&quot;&gt;Например, это может быть копипаст кода вместо создания повторно используемых функций или игнорирование необходимости написания тестов для обеспечения корректной работы кода, что в итоге увеличивает время и затраты на исправление проблем в будущем.&lt;/p&gt;
  &lt;p id=&quot;BtIA&quot;&gt;Поговорим о том как контроллировать техдолг.&lt;/p&gt;
  &lt;h2 id=&quot;uU4e&quot;&gt;Основная информация&lt;/h2&gt;
  &lt;p id=&quot;NqMa&quot;&gt;&lt;strong&gt;SonarQube&lt;/strong&gt; - это инструмент для статического анализа кода, позволяет автоматизировать процесс обнаружения проблем в коде, таких как потенциальные ошибки, нарушения стандартов кодирования, пропущенные возможности оптимизации и другие виды нарушений.&lt;/p&gt;
  &lt;p id=&quot;XwjD&quot;&gt;&lt;strong&gt;Краткие возможности:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;hV7M&quot;&gt;
    &lt;li id=&quot;2GIm&quot;&gt;Выявление потенциальных ошибок, такие как неправильное использование переменных, типов или функций.&lt;/li&gt;
    &lt;li id=&quot;dgNN&quot;&gt;Поддержание стандартов кодирования.&lt;/li&gt;
    &lt;li id=&quot;GhYR&quot;&gt;Анализ производительности, обнаружение участков кода, которые могут вызвать утечки памяти или замедлить производительность приложения.&lt;/li&gt;
    &lt;li id=&quot;guEb&quot;&gt;Управление техническим долгом, контроль метрик. Также с помощью плагинов, можно например &lt;a href=&quot;https://marketplace.atlassian.com/apps/1217471/sonarqube-connector-for-jira?hosting=server&amp;tab=overview&quot; target=&quot;_blank&quot;&gt;ставить задачи в Jira&lt;/a&gt; на исправление участка кода.&lt;/li&gt;
    &lt;li id=&quot;5EHJ&quot;&gt;Сохраняет историю метрик качества кода&lt;/li&gt;
    &lt;li id=&quot;KjOy&quot;&gt;Интеграция с IDE, Jira&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;id-ОбщаяинформацияоSonarQube-Отличиеотлинтеров&quot;&gt;Отличие от линтеров&lt;/h2&gt;
  &lt;p id=&quot;Osuk&quot;&gt;Основная задача линтера — это проверка кода на соответствие определенным стилям и правилам программирования, таким как отступы, использование пробелов, нейминг переменных и т.д.&lt;/p&gt;
  &lt;p id=&quot;RQY6&quot;&gt;Статический анализ кода ориентирован на более широкий аспект анализа кода, включая выявление ошибок, определение потенциальных уязвимостей безопасности, анализ архитектуры и т.д.&lt;/p&gt;
  &lt;h3 id=&quot;id-ОбщаяинформацияоSonarQube-ПочемунехватитESLint,TSLint,Stylelint?&quot;&gt;Почему не хватит ESLint, TSLint, Stylelint?&lt;/h3&gt;
  &lt;p id=&quot;JDL0&quot;&gt;Например для ESLint можно подключить плагин &lt;a href=&quot;https://github.com/SonarSource/eslint-plugin-sonarjs&quot; target=&quot;_blank&quot;&gt;eslint-plugin-sonarjs&lt;/a&gt;, который также сможет обнаруживать баги, code smells и т.д.&lt;/p&gt;
  &lt;p id=&quot;vx5L&quot;&gt;Но теряется главное преимущество SonarQube – отслеживание эволюции кода в дашбордах с настройкой quality gate и подсвечиванием проблем в динамике.&lt;/p&gt;
  &lt;p id=&quot;uvbz&quot;&gt;Также, ESLint, TSLint, Stylelint заточены на определенные языковые эвристики, а SonarQube оценивает картину целиком, например, может найти утекший секрет в CI-конфигурации. Покрыть такой кейс линтером довольно сложно.&lt;/p&gt;
  &lt;p id=&quot;id-ОбщаяинформацияоSonarQube-Новыепроекты&quot;&gt;Линтеры являются хорошим инструментом, но они должны использоваться в сочетании с другими практиками и инструментами, такими как код-ревью, тестирование (e2e, sl, unit), анализ безопасности и регулярную работу над техдолгом, чтобы обеспечить достойное качество кода на протяжении всего жизненного цикла продукта.&lt;/p&gt;
  &lt;h2 id=&quot;id-ОбщаяинформацияоSonarQube-Аналогииальтернативы&quot;&gt;Аналоги и альтернативы&lt;/h2&gt;
  &lt;p id=&quot;egN4&quot;&gt;Среди похожих решение есть &lt;a href=&quot;https://codescene.com/&quot; target=&quot;_blank&quot;&gt;CodeScene&lt;/a&gt;, &lt;a href=&quot;https://about.codecov.io/&quot; target=&quot;_blank&quot;&gt;CodeCov&lt;/a&gt;. Также есть статические анализаторы вроде &lt;a href=&quot;https://pvs-studio.ru/ru/pvs-studio/&quot; target=&quot;_blank&quot;&gt;PVS Studio&lt;/a&gt;, но он не работает с экосистемой JS/TS.&lt;/p&gt;
  &lt;p id=&quot;tZyE&quot;&gt;CodeScene выделяется своей способностью анализа эволюции кода и предсказания будущих изменений. Но к сожалению, у него нет Community Edition (бесплатен для open source) и для получения ключа нужен VPN (не работает в РФ).&lt;/p&gt;
  &lt;p id=&quot;eztG&quot;&gt;CodeCov больше про покрытие кода тестами.&lt;/p&gt;
  &lt;p id=&quot;GVDO&quot;&gt;Поэтому SonarQube является более выигрышным из-за Community Edition, а также обширного набор инструментов для оценки качества кода, покрытия и т.д.&lt;/p&gt;
  &lt;h2 id=&quot;id-ОбщаяинформацияоSonarQube-Плюсыиминусы&quot;&gt;Плюсы и минусы&lt;/h2&gt;
  &lt;p id=&quot;QUHw&quot;&gt;&lt;strong&gt;Плюсы&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;U55z&quot;&gt;
    &lt;li id=&quot;kLV0&quot;&gt;Статический анализ кода – выявляет ошибки, code smells и потенциальные уязвимости.&lt;/li&gt;
    &lt;li id=&quot;ubnh&quot;&gt;Множество поддерживаемых языков (зависит от версии - community, developer, enterprise, data)&lt;/li&gt;
    &lt;li id=&quot;dK5R&quot;&gt;Интеграция с CI системами&lt;/li&gt;
    &lt;li id=&quot;aFEe&quot;&gt;Дашборды и отчеты&lt;/li&gt;
    &lt;li id=&quot;vSiN&quot;&gt;Интеграция сторонних линтеров&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;Cppk&quot;&gt;&lt;strong&gt;Минусы&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;enqn&quot;&gt;
    &lt;li id=&quot;dzEW&quot;&gt;Ресурсозатратность – запуск полного анализа проекта может занимать длительное время&lt;/li&gt;
    &lt;li id=&quot;ABtt&quot;&gt;Сложность настройки – перед внедрением нужно тщательно обдумать какие папки анализировать, какие исключить из анализы, подкрутить правила. Также присутствует некоторая специфичность к версии Java.&lt;/li&gt;
    &lt;li id=&quot;Gats&quot;&gt;Не всегда точные результаты – результаты анализы могут давать ложные срабатывания или пропуски, и иногда требуется ручная проверка.&lt;/li&gt;
    &lt;li id=&quot;yRZY&quot;&gt;Слабая ролевая модель – довольно неудобно настраивать права доступа, назначать фикс багов на определенных людей&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;DPWM&quot;&gt;Экосистема&lt;/h2&gt;
  &lt;p id=&quot;FyyU&quot;&gt;У SonarQube отличная экосистема плагинов как платных, так и бесплатных.&lt;/p&gt;
  &lt;p id=&quot;dNEp&quot;&gt;Например, интеграция с Jira, PDF-отчеты. Есть на что &lt;a href=&quot;https://github.com/SonarQubeCommunity&quot; target=&quot;_blank&quot;&gt;посмотреть&lt;/a&gt;.&lt;/p&gt;
  &lt;figure id=&quot;s7Dg&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://lh7-us.googleusercontent.com/slidesz/AGV_vUfzBdwTUb2hElTEtQ2Y0kx0o8m2pIIlXbQzo4MDID-dIszpNzNNNP9TSPj5n6UUr4lzju_9-X5S-VPVSYJTjOHw2ruLqPqhstdwVKOXfsl68KFJFjLN2xorPimoY_BGiFGrmOrdBqmsK9jipV7sU1JPb8P4k0IE=s2048?key=-Pe2jLKpkioMA9qQvveyLg&quot; width=&quot;461.5&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;DYpq&quot;&gt;&lt;strong&gt;sonarqube-community-branch-plugin&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;NRxY&quot;&gt;В Community Edition нет анализа веток. Но можно использовать плагин &lt;a href=&quot;https://github.com/mc1arke/sonarqube-community-branch-plugin&quot; target=&quot;_blank&quot;&gt;sonarqube-community-branch-plugin&lt;/a&gt;.&lt;/p&gt;
  &lt;figure id=&quot;cFR4&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://lh7-us.googleusercontent.com/slidesz/AGV_vUcDUVrcJOSSqs9DBjDmklO5p4mg5k9EF6D_XhZj_loC3_tXqFaEFqZQaeba7cDgwcLglQV1JpSEDI4JjRW-6WzymNzlA-j0KE7rsbpBuHHjBBxgyMjot53_m5caECRN9ZyxxNxroRYWArEqZPNpCuvM2OgDJe2-=s2048?key=-Pe2jLKpkioMA9qQvveyLg&quot; width=&quot;341&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Ao8Z&quot;&gt;&lt;strong&gt;sonar-gitlab-plugin&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;Dkn4&quot;&gt;С помощью плагина &lt;a href=&quot;https://github.com/gabrie-allaigre/sonar-gitlab-plugin&quot; target=&quot;_blank&quot;&gt;sonar-gitlab-plugin&lt;/a&gt; можно оставлять комментарии к МР.&lt;/p&gt;
  &lt;figure id=&quot;aeYE&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://lh7-us.googleusercontent.com/slidesz/AGV_vUcX2z2a3Te0XmfIIrO4bp_OkQWtJ39O6yRo328nHLhUm8qwFi0jd0YvUgjejU1qjeCZAtcOfrXX_KVt64R9RXn_wCZj09kLEbJm1_3LspZXdEWQemHkbSa4Yx3eNXRO5sGa4BsoMs14oJiYfd7aGY8oZc6sHKsm=s2048?key=-Pe2jLKpkioMA9qQvveyLg&quot; width=&quot;589&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;xNn2&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;b4am&quot;&gt;&lt;strong&gt;Интеграция с IDE&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;R2Oe&quot;&gt;Плагин &lt;a href=&quot;https://www.sonarsource.com/products/sonarlint/&quot; target=&quot;_blank&quot;&gt;SonarLint&lt;/a&gt; доступен во всех популярных редакторах кода.&lt;/p&gt;
  &lt;p id=&quot;BmI3&quot;&gt;На примере VS Code, в данном случае редактор подсветит ошибку с подробным описанием, так же можно перейти прямо в анализатор в браузере и проверить историю.&lt;/p&gt;
  &lt;figure id=&quot;LjoT&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://lh7-us.googleusercontent.com/slidesz/AGV_vUfnK3vRshEcR4oh3f-eMV8n5R4Ud57DW3LAVdetPQ8ExBG6fJ1uBItrIkwKBQ6aZe3ifOvUhwtXAIfH2V2xP-9Zj1LS3ZJN6tqj_XHV2HoLbaGudK50sBR2jwoO6IwegLfrhMBJa_5KVQXgL0vhm6zxXYxEyy68=s2048?key=-Pe2jLKpkioMA9qQvveyLg&quot; width=&quot;860&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;1fiS&quot;&gt;Отличия версий&lt;/h2&gt;
  &lt;p id=&quot;nXIi&quot;&gt;У SonarQube есть несколько версий. Подробнее о разнице версий &lt;a href=&quot;https://www.sonarsource.com/products/sonarqube/downloads/&quot; target=&quot;_blank&quot;&gt;тут&lt;/a&gt;.&lt;/p&gt;
  &lt;ul id=&quot;dRzE&quot;&gt;
    &lt;li id=&quot;KjqT&quot;&gt;&lt;strong&gt;Community Edition&lt;/strong&gt;&lt;/li&gt;
    &lt;ul id=&quot;vBhT&quot;&gt;
      &lt;li id=&quot;KDjc&quot;&gt;Статический анализ кода для 19 языков&lt;/li&gt;
      &lt;li id=&quot;bkKz&quot;&gt;Обнаружение ошибок и базовых уязвимостей&lt;/li&gt;
      &lt;li id=&quot;2hlV&quot;&gt;Ревью security hotspots&lt;/li&gt;
      &lt;li id=&quot;K8lo&quot;&gt;Отслеживание code smells и техдолга&lt;/li&gt;
      &lt;li id=&quot;Qf75&quot;&gt;Метрики code quality и истории&lt;/li&gt;
      &lt;li id=&quot;yhwu&quot;&gt;Интеграция CI/CD&lt;/li&gt;
      &lt;li id=&quot;6tFe&quot;&gt;Плагины от сообщества&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;3wQN&quot;&gt;Developer Edition&lt;/li&gt;
    &lt;ul id=&quot;XGBH&quot;&gt;
      &lt;li id=&quot;emBb&quot;&gt;Поддержка C, C++, Swift, Objective C, T-SQL, PL/SQL.&lt;/li&gt;
      &lt;li id=&quot;Mz6Q&quot;&gt;Обнаружение сложных ошибок и уязвимостей&lt;/li&gt;
      &lt;li id=&quot;6IHu&quot;&gt;Обнаружение ошибок крашей Python/Java&lt;/li&gt;
      &lt;li id=&quot;1uvC&quot;&gt;Анализ Merge Requests&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;luMs&quot;&gt;Enterprise Edition&lt;/li&gt;
    &lt;ul id=&quot;4bX6&quot;&gt;
      &lt;li id=&quot;1afM&quot;&gt;PDF-отчеты&lt;/li&gt;
      &lt;li id=&quot;EdUj&quot;&gt;Отчеты безопасности&lt;/li&gt;
      &lt;li id=&quot;qnp9&quot;&gt;Нормативные отчеты&lt;/li&gt;
      &lt;li id=&quot;JQy1&quot;&gt;Параллельная обработка репортов&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;UJRJ&quot;&gt;Data Center Edition&lt;/li&gt;
    &lt;ul id=&quot;t6fG&quot;&gt;
      &lt;li id=&quot;MPPy&quot;&gt;Горизонтальное масштабирование&lt;/li&gt;
      &lt;li id=&quot;mJnb&quot;&gt;Улучшенный перфоманс и high load&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;O8jg&quot; class=&quot;m_retina&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/3a/c7/3ac7f887-4eeb-460e-834c-94d68a0b2a39.png&quot; width=&quot;575&quot; /&gt;
    &lt;figcaption&gt;Разница в одной картинке&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h1 id=&quot;id-ОбщаяинформацияоSonarQube-Типовыепроблемыкодовойбазы&quot;&gt;Типовые проблемы кодовой базы&lt;/h1&gt;
  &lt;p id=&quot;kzjP&quot;&gt;Команда Sonarqube выделяет несколько &amp;quot;грехов&amp;quot; разработчиков:&lt;/p&gt;
  &lt;ul id=&quot;EuTP&quot;&gt;
    &lt;li id=&quot;wY9D&quot;&gt;Баги и потенциальные баги&lt;/li&gt;
    &lt;li id=&quot;Vj71&quot;&gt;Нарушение стандартов кодирования&lt;/li&gt;
    &lt;li id=&quot;GTpB&quot;&gt;Дублирование кода&lt;/li&gt;
    &lt;li id=&quot;fDE3&quot;&gt;Недостаточное покрытие модульными тестами&lt;/li&gt;
    &lt;li id=&quot;6qMh&quot;&gt;Плохое распределение сложности&lt;/li&gt;
    &lt;li id=&quot;mEOK&quot;&gt;Спагетти-дизайн&lt;/li&gt;
    &lt;li id=&quot;z4vq&quot;&gt;Недостаточно или слишком много комментариев&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;TQz8&quot;&gt;Посмотрим, как SonarQube отслеживает эти проблемы.&lt;/p&gt;
  &lt;h2 id=&quot;id-ОбщаяинформацияоSonarQube-МетрикиSonarQube&quot;&gt;Метрики SonarQube&lt;/h2&gt;
  &lt;p id=&quot;XYdG&quot;&gt;В каждом анализе SonarQube есть несколько метрик.&lt;/p&gt;
  &lt;figure id=&quot;cZTm&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://lh7-us.googleusercontent.com/slidesz/AGV_vUfwudd4dRpLOKF5z0zV_l9wlTEayiRaSP4shstZu24OI9Sv9k0G0lWv-HVH1Oghw6ozG9c1SccaZYxLGKioRzYXHZSn5-uI_XSWsgKly52Cdi2K2YxMNuEhGbd_m3ZElrhViMIEobAiGyOqDzyW4_G7OGBrcr5E=s2048?key=-Pe2jLKpkioMA9qQvveyLg&quot; width=&quot;1263&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;l1x1&quot;&gt;Метрики оцениваются по шкале A до E, где E - наихудший рейтинг, говорящий о том, что был найден минимум один блокирующий баг.&lt;/p&gt;
  &lt;p id=&quot;U9dz&quot;&gt;Рассмотрим основные метрики.&lt;/p&gt;
  &lt;h3 id=&quot;id-ОбщаяинформацияоSonarQube-Issues(Найденныепроблемы)&quot;&gt;Issues (Найденные проблемы)&lt;/h3&gt;
  &lt;p id=&quot;EglJ&quot;&gt;Показывает найденные проблемы в коде&lt;/p&gt;
  &lt;ul id=&quot;7D47&quot;&gt;
    &lt;li id=&quot;sH9w&quot;&gt;🐞 Bug — приоритетные ошибки, которые нужно исправить как можно скорее&lt;/li&gt;
    &lt;li id=&quot;cyEt&quot;&gt;💩 Code smell — незначительные огрехи, которые больше относятся к культуре кода и его оформлению&lt;/li&gt;
    &lt;li id=&quot;4jrf&quot;&gt;🔒 Vulnerability – уязвимости, связанные с безопасностью.&lt;/li&gt;
    &lt;li id=&quot;VfCp&quot;&gt;🛡️ Security HotSpot - потенциальные точки уязвимости&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;JRi8&quot;&gt;У каждой ошибки есть состояния:&lt;/p&gt;
  &lt;ul id=&quot;zn57&quot;&gt;
    &lt;li id=&quot;mxbI&quot;&gt;Открытые&lt;/li&gt;
    &lt;li id=&quot;kb7E&quot;&gt;Переоткрытые&lt;/li&gt;
    &lt;li id=&quot;UQfk&quot;&gt;Подтвержденные&lt;/li&gt;
    &lt;li id=&quot;pYtl&quot;&gt;Ложные&lt;/li&gt;
    &lt;li id=&quot;J0je&quot;&gt;Won&amp;#x27;t fix&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;id-ОбщаяинформацияоSonarQube-Security(Безопасность)&quot;&gt;Security (Безопасность)&lt;/h3&gt;
  &lt;p id=&quot;QpF3&quot;&gt;Это&lt;em&gt; отдельная вкладка &lt;/em&gt;где собрана информация о количестве уязвимостей и их рейтинге безопасности (от A до E). Подробнее &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/user-guide/metric-definitions/#security&quot; target=&quot;_blank&quot;&gt;тут&lt;/a&gt;.&lt;/p&gt;
  &lt;ul id=&quot;jtuM&quot;&gt;
    &lt;li id=&quot;4c19&quot;&gt;A = 0 проблем&lt;/li&gt;
    &lt;li id=&quot;zstr&quot;&gt;B = как минимум 1 Minor проблема&lt;/li&gt;
    &lt;li id=&quot;ZfLS&quot;&gt;C = как минимум 1 Major проблема&lt;/li&gt;
    &lt;li id=&quot;fsgc&quot;&gt;D = как минимум 1 Critical проблема&lt;/li&gt;
    &lt;li id=&quot;mtDA&quot;&gt;E = как минимум 1 Blocker проблема&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;id-ОбщаяинформацияоSonarQube-Reliability(Надежность)&quot;&gt;Reliability (Надежность)&lt;/h3&gt;
  &lt;p id=&quot;ohkZ&quot;&gt;SonarQube анализирует код на предмет надежности, выявляя проблемы, которые могут привести к сбоям, ошибкам выполнения, или другим нежелательным результатам при работе программы.&lt;/p&gt;
  &lt;h3 id=&quot;id-ОбщаяинформацияоSonarQube-Maintainability(Поддерживаемость)&quot;&gt;Maintainability (Поддерживаемость)&lt;/h3&gt;
  &lt;p id=&quot;CJSK&quot;&gt;Во вкладке &lt;em&gt;Measures в разделе Maintainability &lt;/em&gt;содержится информация о техническом долге в проекте.&lt;/p&gt;
  &lt;ul id=&quot;RjT1&quot;&gt;
    &lt;li id=&quot;N20c&quot;&gt;Duplications&lt;/li&gt;
    &lt;li id=&quot;eQNv&quot;&gt;Technical debt&lt;/li&gt;
    &lt;li id=&quot;8bRN&quot;&gt;Code complexity&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;id-ОбщаяинформацияоSonarQube-Coverage(Покрытиетестами)&quot;&gt;Coverage (Покрытие тестами)&lt;/h3&gt;
  &lt;p id=&quot;zuhe&quot;&gt;Во вкладке &lt;em&gt;Measures&lt;/em&gt; в разделе &lt;em&gt;Coverage&lt;/em&gt; собрана информация о покрытии кода тестами.&lt;/p&gt;
  &lt;p id=&quot;ibyn&quot;&gt;Может быть полезно для:&lt;/p&gt;
  &lt;ul id=&quot;zJ53&quot;&gt;
    &lt;li id=&quot;XGjA&quot;&gt;Оценки качества тестирования&lt;/li&gt;
    &lt;li id=&quot;Nrdv&quot;&gt;Выявление неиспользуемого кода&lt;/li&gt;
    &lt;li id=&quot;LhEI&quot;&gt;Стимулирование написания новых тестов&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;id-ОбщаяинформацияоSonarQube-Duplications(Дублирование)&quot;&gt;Duplications (Дублирование)&lt;/h3&gt;
  &lt;p id=&quot;Cz3A&quot;&gt;Во вкладке &lt;em&gt;Measures&lt;/em&gt; в разделе &lt;em&gt;Duplications&lt;/em&gt; можно найти информацию о наличии дублирующегося кода.&lt;/p&gt;
  &lt;p id=&quot;id-ОбщаяинформацияоSonarQube-Настройкаисключенийдлядублей&quot;&gt;&lt;strong&gt;Настройка исключений для дублей&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;E3fa&quot;&gt;При настройке проекта нужно подумать над тем какие кейсы могут быть ложно-положительными и настройте исключения для них.&lt;/p&gt;
  &lt;p id=&quot;wQHD&quot;&gt;К таким же исключениям потенциально можно отнести любой автоген который хранится в репозитории, например, GQL-схемы.&lt;/p&gt;
  &lt;h2 id=&quot;4Xnw&quot;&gt;Настройка проекта&lt;/h2&gt;
  &lt;p id=&quot;sRCT&quot;&gt;&lt;strong&gt;Quality Profile (Профиль качества):&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;w1hM&quot;&gt;
    &lt;li id=&quot;FHfy&quot;&gt;Это набор правил статического анализа кода, определяющий ожидаемый стандарт качества кода.&lt;/li&gt;
    &lt;li id=&quot;mvuO&quot;&gt;Включает в себя набор правил по стилю кода, безопасности, производительности и другим аспектам.&lt;/li&gt;
    &lt;li id=&quot;bNec&quot;&gt;Позволяет настроить параметры анализа для конкретного проекта или команды разработчиков.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;pHq2&quot;&gt;&lt;strong&gt;Quality Gate (Контроль качества):&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;6Rue&quot;&gt;
    &lt;li id=&quot;1z96&quot;&gt;Это набор условий, которые определяют уровень качества кода, который необходим для успешного прохождения анализа.&lt;/li&gt;
    &lt;li id=&quot;2WNw&quot;&gt;Включает в себя метрики, такие как покрытие кода тестами, процент дублирования кода, количество критических ошибок и т. д.&lt;/li&gt;
    &lt;li id=&quot;waZB&quot;&gt;Если код не соответствует установленным критериям качества, Quality Gate не проходит, и разработчики получают уведомления о необходимости исправлений.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;ltmF&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/a3/a6/a3a65063-3447-4bf8-b8c7-6084852e6de9.png&quot; width=&quot;402&quot; /&gt;
  &lt;/figure&gt;
  &lt;h1 id=&quot;id-ОбщаяинформацияоSonarQube-Списокправил&quot;&gt;Список правил&lt;/h1&gt;
  &lt;p id=&quot;Ou3b&quot;&gt;У SonarQube есть готовые правила валидации для разных языков. Основные правила работают из коробки.&lt;/p&gt;
  &lt;p id=&quot;7MXH&quot;&gt;Правила – это набор валидаций которые помогают найти баги, &amp;quot;code smells&amp;quot; и проблемы безопасности в ходе статистического анализа.&lt;/p&gt;
  &lt;p id=&quot;Spg0&quot;&gt;Список правил:&lt;/p&gt;
  &lt;ul id=&quot;hx4W&quot;&gt;
    &lt;li id=&quot;gTkv&quot;&gt;&lt;a href=&quot;https://rules.sonarsource.com/javascript/&quot; target=&quot;_blank&quot;&gt;JavaScript&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;fvEV&quot;&gt;&lt;a href=&quot;https://rules.sonarsource.com/typescript/&quot; target=&quot;_blank&quot;&gt;TypeScript&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;5FLE&quot;&gt;&lt;a href=&quot;https://rules.sonarsource.com/css/&quot; target=&quot;_blank&quot;&gt;CSS&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;02w3&quot;&gt;Также можно добавлять &lt;em&gt;свои правила&lt;/em&gt; (&lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/extension-guide/adding-coding-rules/&quot; target=&quot;_blank&quot;&gt;подробнее тут&lt;/a&gt;).&lt;/p&gt;
  &lt;h2 id=&quot;id-ОбщаяинформацияоSonarQube-lintersИнтеграциястороннихлинтеров&quot;&gt;Интеграция сторонних линтеров&lt;/h2&gt;
  &lt;p id=&quot;Ejym&quot;&gt;Для улучшения качества репортов SonarQube можно дать ему больше информации, например отчеты Stylelint, ESLint, TSLint через параметры.&lt;/p&gt;
  &lt;ul id=&quot;z5VD&quot;&gt;
    &lt;li id=&quot;Clqe&quot;&gt;sonar.css.stylelint.reportPaths&lt;/li&gt;
    &lt;li id=&quot;5S2G&quot;&gt;sonar.eslint.reportPaths&lt;/li&gt;
    &lt;li id=&quot;N7Ay&quot;&gt;sonar.typescript.tslint.reportPaths&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;6BPA&quot;&gt;Подробнее в &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/importing-external-issues/external-analyzer-reports/&quot; target=&quot;_blank&quot;&gt;документации&lt;/a&gt;.&lt;/p&gt;
  &lt;h3 id=&quot;id-ВнедрениеSonarQubeвпроект(инструкция)-СозданиепроектавSonarQube&quot;&gt;Создание проекта в SonarQube&lt;/h3&gt;
  &lt;p id=&quot;da1m&quot;&gt;В UI SonarQube в разделе создания проекта, укажите ключ и название проекта.&lt;/p&gt;
  &lt;p id=&quot;41Ba&quot;&gt;&lt;em&gt;Рекомендация: ключ должен совпадать с путем в Gitlab/Github. Например, путь в Gitlab &lt;u&gt;gitlab.com/frontend/awesome-project&lt;/u&gt;, значит ключ &lt;u&gt;awesome-project&lt;/u&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
  &lt;figure id=&quot;CfcW&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/1d/6b/1d6bb90e-d152-472e-9225-b99566abbde9.png&quot; width=&quot;473&quot; /&gt;
  &lt;/figure&gt;
  &lt;h4 id=&quot;id-ВнедрениеSonarQubeвпроект(инструкция)-tokenСозданиетокена&quot;&gt;Создание токена&lt;/h4&gt;
  &lt;p id=&quot;M0Z5&quot;&gt;&lt;em&gt;Рекомендация: используйте формат &lt;u&gt;sonar-token-{PROJECT_KEY}&lt;/u&gt;. Например, &lt;u&gt;sonar-token-awesome-project.&lt;/u&gt;&lt;/em&gt;&lt;/p&gt;
  &lt;figure id=&quot;ND0O&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/1f/7c/1f7c26f2-86e8-407e-b2ab-d09158ce8920.png&quot; width=&quot;682&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;ZYPe&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/50/f9/50f987d6-98fa-46eb-95e5-e8786cb5512c.png&quot; width=&quot;580&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;id-ВнедрениеSonarQubeвпроект(инструкция)-Настройкарепозитория&quot;&gt;Настройка репозитория&lt;/h3&gt;
  &lt;p id=&quot;gw7M&quot;&gt;Добавьте в .gitignore игнор файлов результатов анализа SonarQube.&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre id=&quot;iDau&quot; data-lang=&quot;bash&quot;&gt;# SonarQube
.sonar/
.scannerwork/ &lt;/pre&gt;
  &lt;/section&gt;
  &lt;p id=&quot;Dopj&quot;&gt;В корне репозитория нужно создать файл &lt;strong&gt;sonar-project.properties&lt;/strong&gt;. В нем указываются основные проекты, такие как хост SonarQube, название и ключ проекта, папки для сканирования.&lt;/p&gt;
  &lt;p id=&quot;ifab&quot;&gt;Описание всех параметров можно найти &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/analysis-parameters/&quot; target=&quot;_blank&quot;&gt;тут&lt;/a&gt;.&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre id=&quot;YEoM&quot; data-lang=&quot;bash&quot;&gt;# Хост SonarQube
sonar.host.url=https://sonarqube.company.domain

# Ключ и название проекта
sonar.projectKey=awesome-project
sonar.projectName=awesome-project

# Список относительных путей, где хранится исходный код
sonar.sources=src

# Кодировка для проекта, обычно UTF-8
sonar.sourceEncoding=UTF-8

# Список относительных путей, которые необходимо исключить для анализа
sonar.exclusions=

# Список относительных путей, где хранятся тесты
sonar.tests=

# Ожидание завершения анализа на сервере (пригодится для вебхуков)
sonar.qualitygate.wait=true&lt;/pre&gt;
  &lt;/section&gt;
  &lt;h3 id=&quot;id-ВнедрениеSonarQubeвпроект(инструкция)-НастройкавGitlabCI&quot;&gt;Настройка в Gitlab CI&lt;/h3&gt;
  &lt;p id=&quot;BKPO&quot;&gt;Это пример настройки в Gitlab CI.&lt;/p&gt;
  &lt;p id=&quot;qLRM&quot;&gt;Переменные &lt;em&gt;sonar.login, sonar.projectVersion, sonar.projectDate&lt;/em&gt; передаются через аргументы CLI.&lt;/p&gt;
  &lt;ul id=&quot;nFMb&quot;&gt;
    &lt;li id=&quot;jIaO&quot;&gt;&lt;strong&gt;sonar.login&lt;/strong&gt; – токен, полученный при создании проекта в SonarQube.&lt;/li&gt;
    &lt;li id=&quot;w8Jd&quot;&gt;&lt;strong&gt;sonar.projectVersion&lt;/strong&gt;&lt;em&gt; – &lt;/em&gt;тег релиза, например &lt;code&gt;CI_COMMIT_TAG&lt;/code&gt;&lt;/li&gt;
    &lt;li id=&quot;PbGE&quot;&gt;&lt;strong&gt;sonar.projectDate&lt;/strong&gt; – уникальная дата релиза. SonarQube выдаст ошибку если дата актуальной статы старше последней существующей статы. Например релизы 36.0.0 и 36.0.1 сделаны 01.10.2024, в таком случае SonarQube выдаст ошибку&lt;code&gt;Validation of project failed: Date of analysis cannot be older than the date&lt;/code&gt; &lt;code&gt;of the last known analysis on this project. Value: &amp;quot;2023-10-01T07:02:00+0000&amp;quot;. Latest analysis: &amp;quot;2024-10-01T07:01:57+0000&amp;quot;. It&amp;#x27;s only possible to rebuild the past in&lt;/code&gt; &lt;code&gt;a chronological order.&lt;/code&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;xKsB&quot;&gt;Пример джобы в Gitlab CI.&lt;/p&gt;
  &lt;pre id=&quot;HChw&quot; data-lang=&quot;yaml&quot;&gt;sonarqube-check:
  stage: check
  tags:
    - prod
  image:
    name: sonarsource/sonar-scanner-cli:4.8.1
    entrypoint: [&amp;#x27;&amp;#x27;]
  cache: 
    key: &amp;#x27;${CI_JOB_NAME}&amp;#x27;
    paths:
      - .sonar/cache
  variables:
    SONAR_USER_HOME: &amp;#x27;${CI_PROJECT_DIR}/.sonar&amp;#x27;
    GIT_DEPTH: &amp;#x27;0&amp;#x27;
  script:
    - current_tag=${CI_COMMIT_TAG}
    - echo $current_tag
    - current_date=$(date -u +&amp;quot;%Y-%m-%dT%H:%M:%S%z&amp;quot;)
    - echo $current_date
    - sonar-scanner -Dsonar.login=${SONAR_LOGIN} -Dsonar.projectVersion=$current_tag -Dsonar.projectDate=$current_date
  allow_failure: true
  rules:
    - if: $CI_COMMIT_BRANCH == &amp;quot;master&amp;quot;&lt;/pre&gt;
  &lt;h3 id=&quot;id-ВнедрениеSonarQubeвпроект(инструкция)-Генерацияисториистатов&quot;&gt;Генерация истории статов&lt;/h3&gt;
  &lt;p id=&quot;r6GD&quot;&gt;Для того чтобы сразу начать работу с техдолгом, нужно сгенерировать историю отчетов.&lt;/p&gt;
  &lt;p id=&quot;Vxu3&quot;&gt;Для этого написан &lt;a href=&quot;https://gist.github.com/yangirov/92928bea113dbdf2a7cdd719d9b942c6&quot; target=&quot;_blank&quot;&gt;скрипт&lt;/a&gt;, который переходит в указанный репозиторий, перемещается по тегам релизов и сканирует релизы через &lt;code&gt;sonar-scanner&lt;/code&gt;.&lt;/p&gt;
  &lt;p id=&quot;mCER&quot;&gt;Сохраните скрипт &lt;code&gt;index.js&lt;/code&gt; в любую папку на компьютере и выполните:&lt;/p&gt;
  &lt;pre id=&quot;zWhF&quot;&gt;npm init
npm i simple-git&lt;/pre&gt;
  &lt;p id=&quot;4yTB&quot;&gt;В переменной &lt;strong&gt;&lt;code&gt;repositoryPath&lt;/code&gt;&lt;/strong&gt; указывается путь до репозитория проекта.&lt;/p&gt;
  &lt;p id=&quot;zd6k&quot;&gt;В переменной &lt;strong&gt;&lt;code&gt;sonarScannerCliPath&lt;/code&gt;&lt;/strong&gt; указывается путь до &lt;code&gt;sonar-scanner-cli&lt;/code&gt;. Скачать можно &lt;a href=&quot;https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/scanners/sonarscanner/#running-from-zip-file&quot; target=&quot;_blank&quot;&gt;тут&lt;/a&gt;.&lt;/p&gt;
  &lt;p id=&quot;kfDe&quot;&gt;В &lt;strong&gt;объекте config&lt;/strong&gt; указывается основная информация&lt;/p&gt;
  &lt;ul id=&quot;GQfH&quot;&gt;
    &lt;li id=&quot;G7lN&quot;&gt;sonar.host.url - хост SonarQube&lt;/li&gt;
    &lt;li id=&quot;yAy3&quot;&gt;sonar.login - токен проекта SonarQube&lt;/li&gt;
    &lt;li id=&quot;zfMx&quot;&gt;sonar.projectKey - ключ проекта&lt;/li&gt;
    &lt;li id=&quot;CC0e&quot;&gt;sonar.projectName - название проекта (рекомендую чтобы совпадал с ключом)&lt;/li&gt;
    &lt;li id=&quot;ymfA&quot;&gt;sonar.sources - папки для сканирования&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;08HI&quot;&gt;Далее для начала генерации отчетов запустите скрипт.&lt;/p&gt;
  &lt;p id=&quot;nieB&quot;&gt;&lt;code&gt;node index.js&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;OPUJ&quot;&gt;Если релизов много, скрипт может выполняться &lt;strong&gt;несколько часов&lt;/strong&gt;. После этого в дашборде появится стата по каждому релизу.&lt;/p&gt;
  &lt;h3 id=&quot;aLNV&quot;&gt;Интеграция через вебхуки&lt;/h3&gt;
  &lt;p id=&quot;RtXf&quot;&gt;А с помощью вебхуков можно настраивать различные автоматизации. Например, отчет о проверке релиза в чат команды.&lt;/p&gt;
  &lt;figure id=&quot;VdZw&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/0f/c4/0fc41d40-211f-4523-b3b0-fa43ce53a556.png&quot; width=&quot;294&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;hIPl&quot;&gt;На этом всё, надеюсь статья была полезной.&lt;/p&gt;
  &lt;p id=&quot;XKq1&quot;&gt;Если вам было интересно, подписывайтесь на телеграм-канал &lt;a href=&quot;https://t.me/s/trash_js&quot; target=&quot;_blank&quot;&gt;@trash_js&lt;/a&gt; – там я пишу более короткие заметки об экосистеме фронтенда и frontops. 🎩 &lt;/p&gt;

</content></entry><entry><id>yangirov:apache-kafka-notes</id><link rel="alternate" type="text/html" href="https://blog.yangirov.ru/apache-kafka-notes?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=yangirov"></link><title>Заметки об Apache Kafka</title><published>2022-08-23T07:46:51.484Z</published><updated>2022-09-29T12:31:24.369Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/76/77/76776b1b-8ef7-470f-aee6-0e57a2464809.png"></media:thumbnail><category term="razrabotka" label="Разработка"></category><summary type="html">&lt;img src=&quot;https://lh3.googleusercontent.com/xubAXA3t4lfSVI-9pCBLAxyqsDE2CdNKszps7INiX3GqGsDi3AJfPitd0LbzEgPlZrVT0S5cbhtGr-JvOLjJaHOljieDqusLYH0i2suEGS8UwSvwwkgrEBV-3dN8dtHg5YlpEorJmK1VRzzgdC9C_UpfEFzxA--ehZzvUkAtE92rDQP6keVjbJ3LcTA&quot;&gt;Apache Kafka — распределенный, масштабируемый и отказоустойчивый лог, способный записывать миллионы записей в секунду. 💪</summary><content type="html">
  &lt;p id=&quot;qCS5&quot;&gt;&lt;strong&gt;Apache Kafka &lt;/strong&gt;— распределенный, масштабируемый и отказоустойчивый лог, способный записывать миллионы записей в секунду. 💪&lt;/p&gt;
  &lt;p id=&quot;Zoxz&quot;&gt;&lt;strong&gt;Можно&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;gGPN&quot;&gt;
    &lt;li id=&quot;RHUM&quot;&gt;записать сообщение в топик&lt;/li&gt;
    &lt;li id=&quot;d9lH&quot;&gt;прочитать записи из топика&lt;/li&gt;
    &lt;li id=&quot;irDi&quot;&gt;закоммитить место до которого дочитали&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;ZKz2&quot;&gt;&lt;strong&gt;Ограничения&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;IcBz&quot;&gt;
    &lt;li id=&quot;UNlk&quot;&gt;нельзя удалить сообщение&lt;/li&gt;
    &lt;li id=&quot;Fcko&quot;&gt;нельзя изменить сообщение&lt;/li&gt;
    &lt;li id=&quot;2pzJ&quot;&gt;поиск работает только по идентификатору&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;6xK2&quot;&gt;&lt;strong&gt;Компоненты&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;vKN5&quot;&gt;
    &lt;li id=&quot;OjFR&quot;&gt;&lt;strong&gt;Topic&lt;/strong&gt;: категория сообщений по какому-то типу.&lt;/li&gt;
    &lt;li id=&quot;XQ4t&quot;&gt;&lt;strong&gt;Broker&lt;/strong&gt;: кластер (нода).&lt;/li&gt;
    &lt;li id=&quot;q53A&quot;&gt;&lt;strong&gt;Producer&lt;/strong&gt;: производители публикуют данные в топиках.&lt;/li&gt;
    &lt;li id=&quot;MrBl&quot;&gt;&lt;strong&gt;Consumer&lt;/strong&gt;: потребители это сервисы, которые подписываются на топики.&lt;/li&gt;
    &lt;li id=&quot;SfZM&quot;&gt;&lt;strong&gt;Zookeeper&lt;/strong&gt;: интерфейс координации между брокерами и потребителями Кафки.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;mXlt&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://lh3.googleusercontent.com/xubAXA3t4lfSVI-9pCBLAxyqsDE2CdNKszps7INiX3GqGsDi3AJfPitd0LbzEgPlZrVT0S5cbhtGr-JvOLjJaHOljieDqusLYH0i2suEGS8UwSvwwkgrEBV-3dN8dtHg5YlpEorJmK1VRzzgdC9C_UpfEFzxA--ehZzvUkAtE92rDQP6keVjbJ3LcTA&quot; width=&quot;682&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;Oghp&quot;&gt;Подробнее&lt;/h2&gt;
  &lt;h3 id=&quot;BYlO&quot;&gt;&lt;strong&gt;Топик&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;W5vk&quot;&gt;В Кафке, темы разделены и каждый раздел представлен упорядоченным списком последовательных сообщений. Кластер Кафки поддерживает раздельное журналирование (логирование) для каждой темы. Каждому сообщению в разделе присваивается уникальный идентификатор. &lt;/p&gt;
  &lt;p id=&quot;Abqb&quot;&gt;Топик это по сути файл, лог. Топик разбит на партиции, нумеруются с нуля. А уже внутри партиции есть сообщения, в пределах одной партиции сообщения приходят по принципу FIFO, FIRST IN, FIRST OUT.&lt;/p&gt;
  &lt;p id=&quot;tXZh&quot;&gt;Кафка гарантирует что &lt;strong&gt;то что попало в Кафку, из нее не пропадет.&lt;/strong&gt;&lt;/p&gt;
  &lt;h3 id=&quot;rTXF&quot;&gt;&lt;strong&gt;Брокер&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;FlqQ&quot;&gt;Обычно состоит из одного или нескольких серверов, и каждый из них может иметь один или несколько запущенных серверных процесса которые называются брокером. Топики создаются в контексте процессов брокера.&lt;/p&gt;
  &lt;h3 id=&quot;29zv&quot;&gt;&lt;strong&gt;Zookeeper&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;fQtK&quot;&gt;По сути это распределенная система необходимая для отказоустойчивости брокеров. В этой системе хранятся метаданные необходимые кафке. Например, через нее выбираются лидирующие брокеры для определенных партиций или происходит ребалансировка если отказывает какая-то нода.&lt;/p&gt;
  &lt;h2 id=&quot;y8TT&quot;&gt;Отказоустойчивость&lt;/h2&gt;
  &lt;figure id=&quot;RG9g&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://lh4.googleusercontent.com/ZFArOND3kELoSkwoJDULC1xKQDoT0Gh9NK12OUWOgCDOuJ0q8C6rGM2UgEj7rAIN8wElhwAxwCdYJT5J_bMo6rFI-F9eFHlogUX5Q-HlOfXE5MmZomtQEzwCiJizjnb1keGp9whsZ4hIdCDGfs7LFTgbIbM6DFXG1fGoyP74HyoK95cyIUedYOUuA2E&quot; width=&quot;600&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;nbwb&quot;&gt;Такая устойчивость возникает за счёт репликаций партиций.&lt;/p&gt;
  &lt;p id=&quot;5N3h&quot;&gt;Каждый  брокер может быть для партиции лидирующим. И кроме того эти партиции реплицируются на соседние брокеры (по мере возможности). Таким образом запись идет на несколько нод в кластере.&lt;/p&gt;
  &lt;p id=&quot;PU7r&quot;&gt;&lt;em&gt;Допустим один из брокеров упал. Что произойдет?&lt;/em&gt;&lt;/p&gt;
  &lt;p id=&quot;oJif&quot;&gt;Произойдет ребалансировка, переопределение лидера, а так как у нас есть реплика партиции, то данные мы не теряем и продолжаем читать данные оттуда где они есть. После того как упавший брокер возобновит работу (или мы поднимем новый) у нас произойдет репликация партиции и всё становится как прежде. Через какое-то время ребалансировка снова произойдет.&lt;/p&gt;
  &lt;p id=&quot;pa8c&quot;&gt;И это всё работает магически под капотом, нам не нужно думать о том как работает кафка для сохранения наших данных.&lt;/p&gt;
  &lt;h2 id=&quot;gFdq&quot;&gt;Сообщение&lt;/h2&gt;
  &lt;figure id=&quot;x2gN&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://lh6.googleusercontent.com/2oqmLnYwrTj2Xw-wz_q9Jy2Z-FZ_hHLz4vPjWT8FJucitH82uxgbZ-IIDw3IREzivZDqiqtYDRpXTISd4jx0i1KIXEtvCBzFqnxnfp16lXSs0Lm7S6QvfqAQf1ncCqhp9yjMXzdonqTZK-k7o2sJotCWoq7rK3O2rIFLyA-QQyJuk9bIiU2xfkyHHyY&quot; width=&quot;465&quot; /&gt;
  &lt;/figure&gt;
  &lt;ul id=&quot;nbJG&quot;&gt;
    &lt;li id=&quot;jS1g&quot;&gt;&lt;strong&gt;Номер партиции&lt;/strong&gt; - потому что сообщение отправляется не прямо в топик, а в конкретную партицию.&lt;/li&gt;
    &lt;li id=&quot;7I18&quot;&gt;&lt;strong&gt;Ключ&lt;/strong&gt; - обычно байтовые значения или гуид. Так то неважно.&lt;/li&gt;
    &lt;li id=&quot;7p4h&quot;&gt;&lt;strong&gt;Значение&lt;/strong&gt; - полезная инфа.&lt;/li&gt;
    &lt;li id=&quot;MCo3&quot;&gt;&lt;strong&gt;Заголовки&lt;/strong&gt; - мета-данные.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;sSse&quot;&gt;Номер партиции можно выбирать самостоятельно так и автоматически через ключ (мы берем ключ, вычисляем хэш-функцию и делим на количество партиций, таким образом записи равномерно распределяется по партициям).&lt;/p&gt;
  &lt;h3 id=&quot;sudW&quot;&gt;Пропускная способность и время ожидания&lt;/h3&gt;
  &lt;p id=&quot;4ojB&quot;&gt;Представим, что нам нужно посылать очень много маленьких сообщений. Если мы каждое сообщение будем отправлять как отдельный вызов апи, это будет неэффективно.&lt;/p&gt;
  &lt;p id=&quot;0Z0L&quot;&gt;Кафка-продюсер умеет группировать  сообщения. Мы можем настроить размер группы и время ожидания. По сути это как маршрутка :-)&lt;/p&gt;
  &lt;figure id=&quot;1bli&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://lh6.googleusercontent.com/tTfJfqJpJrx0QA5xDAzmlg1YhFwA2BdNqLbvaOj4vPeATwmXvgkDnsD4Qk_lrOB3mjThhsPe6C7VlDtXyRxDGia_0Oxu1duz-nZn5y9w4H6FdpehxeFS3UdYxUzwlhO26oUnkYmpI3dEeqJeJVosBUNvMuFxfcwVnY281sz_WYEaFt5VD5Cev8kFWdA&quot; width=&quot;704&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;FxsM&quot;&gt;Запись&lt;/h2&gt;
  &lt;p id=&quot;xnW1&quot;&gt;&lt;em&gt;Как убедиться что записи отправленные в Кафку вообще там сохранены? &lt;/em&gt;&lt;/p&gt;
  &lt;p id=&quot;9F4Z&quot;&gt;Есть несколько режимов (acks)&lt;/p&gt;
  &lt;ul id=&quot;5pX3&quot;&gt;
    &lt;li id=&quot;2Zwo&quot;&gt;Простой режим, кафка просто подтверждает что сообщение дошло. Если упал брокер до записи сообщения, то сообщение потеряется.&lt;/li&gt;
    &lt;li id=&quot;NhyK&quot;&gt;При записи. Подтверждаем запись только в момент записи на диск. На случай если хард отлетит.&lt;/li&gt;
    &lt;li id=&quot;1vIv&quot;&gt;Бронебойный. Подтверждаем только когда сообщение реплицировались на все брокеры. Медленно, но гарантия ~100%.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;zpEO&quot;&gt;Чем более параноидальный режим тем больше задержка и проблем. Можно отлететь по таймауту. И что выбирать зависит от задачи.&lt;/p&gt;
  &lt;h2 id=&quot;2Wwu&quot;&gt;Чтение&lt;/h2&gt;
  &lt;p id=&quot;NcbA&quot;&gt;Как устроено чтение? Каждый консьюмер входит в какую-то группу.&lt;/p&gt;
  &lt;p id=&quot;aBpj&quot;&gt;Если консьюмер один, он читает данные из всех партиций. Но что если данных слишком много?&lt;/p&gt;
  &lt;figure id=&quot;pXS9&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://lh3.googleusercontent.com/AVB4RQB9QBoZH6zZ7zyZeL-B3_GQ6KrAeucKQd62mSJPTywaZzLO50jycmfi3utzu3ttru1KCNqP5WIV2X6wEinij8Pqov-IUTpIuSfwaCBQ4CQhx2okrBi60XO22i5IEMDK8poW1H97Tv17DtOYhqIAOxCYv2dD9ab1HOMF1vjhhF23hhfCCdKQPFM&quot; width=&quot;355&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;TLbu&quot;&gt;Мы можем сделать больше консьюмеров. И кафка сама ребалансирует те партиции которые назначены на определенный консьюмер.&lt;/p&gt;
  &lt;figure id=&quot;FMNM&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://lh4.googleusercontent.com/Ku65AwF2V143rk5f3Zw_N15LQbFkhi609DImhFGZ0gonZzJCdupjhdbR3KVDfi-Vz8xI01JHgCWz6zytWR2yhAWPARMtDyBzOMEVhHPB77hwaqWOFH1IHKv7xhs0QYYaRNtfJBgXvkq59TVwVQK_5hqIdDmYPgFlBmKq8I6HTuddhbBgE_Di940JHMA&quot; width=&quot;355&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;bGae&quot;&gt;Но количество консьюмеров не должно быть больше чем количество партиций. Т.е. число партиций определяет максимальный параллелизм с которым мы можем обрабатывать данные.&lt;/p&gt;
  &lt;p id=&quot;9qEX&quot;&gt;Конечно мы можем сделать лишний, но он ничего не будет делать.&lt;/p&gt;
  &lt;figure id=&quot;oTYc&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://lh6.googleusercontent.com/t-TSoxHqdRj68xtoYWogv565mHeAffjJgnOrTni3gPIpnfpPtpbVpmkNd88qQ3diKMlxHcnal0i9jRVYnotBFaEMl5JamSicwPNNnACtnCr8S-ZMM4EVpkX5cpTnNmYS4EENgrZaEoS4aXM24k-RHRs54jDpcb4Zl3LnG5gQ5N8Sx3swPwnGYL-UYQA&quot; width=&quot;355&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;9Jlb&quot;&gt;Про offset commit&lt;/h2&gt;
  &lt;p id=&quot;wdqY&quot;&gt;Для надежного чтения предусмотрена такая вещь как офсет коммит.&lt;/p&gt;
  &lt;p id=&quot;SX89&quot;&gt;Вот мы прочитали батч записей, обработали и перед чтением следующего блока в кафку отправляется коммит с офсетом.&lt;/p&gt;
  &lt;p id=&quot;Inqk&quot;&gt;Например, консьюмер умер при чтении какого-то сообщения. В таком случае произойдет ребалансировка и сообщения прочитаются с последнего офсета.&lt;/p&gt;
  &lt;p id=&quot;aJFB&quot;&gt;Таким образом мы избавляемся от необходимости повторного чтения записей с самого начала, но мы не полностью гарантированы конечно от повторного чтения.&lt;/p&gt;
  &lt;p id=&quot;h2su&quot;&gt;В кафке чтения это запись в служебный топик.&lt;/p&gt;
  &lt;figure id=&quot;l1FX&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://lh3.googleusercontent.com/Cjb83dE1_SQdG1W6_FfiOMA0Iy0yLS6az6e1V09tRNv-s4WHJqug3eSAseP_QHpMWcG-l6VjIFz4DCPTctUgVfN8v-7MXMUzoW6BIlEqF82j_E5bRiSzHO7S_l-zQTZLUX85KAOSO7CsyJtPcQkh6uADW0i2F-TBuGWW2GxS0RnoD7--RGGfRQ5SUb0&quot; width=&quot;403.5&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;rfqH&quot;&gt;Retention policy&lt;/h2&gt;
  &lt;p id=&quot;mW3Y&quot;&gt;Я говорил что из кафки нельзя удалять сообщения. Но диск не бесконечный. Поэтому в кафке есть такое понятие как ретеншн. Например мы хотим хранить только последний миллион сообщений или гигабайт.&lt;/p&gt;
  &lt;p id=&quot;pK7e&quot;&gt;Как только заполняется сегмент, он удаляется.&lt;/p&gt;
  &lt;figure id=&quot;ir5G&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://lh4.googleusercontent.com/NDifw6D8dpxxzHYMqb7VrQzQLeODGPQCTA7lBpI3rXl8Zh_EEn80KAsBID792dBc65T-wOtIslUyJvXLajw00easW-EnPLOAo-zE9pxGRcII4Fm8-uewZUtgM9FZLqQKC1BQXWrPsYSOgoll8HFWGGgu9U7XsVsyScKNtZIGby1r-5wtjXVxLZVadaw&quot; width=&quot;788&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;ZDXN&quot;&gt;Как это может выглядеть всё вмесчте&lt;/h2&gt;
  &lt;figure id=&quot;W5rk&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://lh4.googleusercontent.com/qGmvzJyXgPCOnxinW8FrDthUDmzl_PPm1eOaR4YLM1108mX-hcouJcNb90zb_D5DnjMMpNaz81s8yE31mfOkNk3IVA5NPzCbQ24gAYvNjMx9D8J7A5fXSGWRBQtdZHZBCcLami5oRYNGT7f5pzUNtT9wIrGcwGMBgIycsjJN-iikUGR91taE81yp58A&quot; width=&quot;725&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;bBu9&quot;&gt;Полезности&lt;/h2&gt;
  &lt;p id=&quot;MPv4&quot;&gt;&lt;a href=&quot;https://www.confluent.io/resources/kafka-the-definitive-guide-v2/&quot; target=&quot;_blank&quot;&gt;Полезная книжка&lt;/a&gt;&lt;/p&gt;
  &lt;figure id=&quot;Kgjm&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://lh4.googleusercontent.com/sLr8iXNalQyeUqkN4-ttmzHBS6irAO-Ilb0e-OZWoswrVd-FvV6XhyOy5LaRjnpsS5I_v_f8CfQ2c0wdEY2hHAtFUYpZQw-1R3ztjUaviTwhxorpOtZWTpyFnY2gW9Mm3nae1GROsjH6Ar3goSZJUE0-JF307WEf-a6WMN8tzo5P7ODtDmG5oUgBTNU&quot; width=&quot;381&quot; /&gt;
  &lt;/figure&gt;

</content></entry><entry><id>yangirov:commits-convention</id><link rel="alternate" type="text/html" href="https://blog.yangirov.ru/commits-convention?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=yangirov"></link><title>Конвенция текста коммитов</title><published>2022-08-22T06:46:39.203Z</published><updated>2024-04-05T09:05:21.668Z</updated><summary type="html">&lt;img src=&quot;https://img2.teletype.in/files/d9/50/d950ad51-9671-4750-8677-b86db83f3cbe.png&quot;&gt;Чтобы сохранить единообразие коммитов и не путаться при поиске по репозиторию, можно подключить к проекту линтер коммитов, который проверяет текст коммитов на соответствие правилам разработки. Проверка происходит на хуке commit-msg с помощью husky, simple-git-hooks или git-hooks.</summary><content type="html">
  &lt;p id=&quot;NiiI&quot;&gt;Чтобы сохранить единообразие коммитов и не путаться при поиске по репозиторию, можно подключить к проекту &lt;a href=&quot;https://commitlint.js.org/&quot; target=&quot;_blank&quot;&gt;линтер коммитов&lt;/a&gt;, который проверяет текст коммитов на соответствие правилам разработки. Проверка происходит на хуке commit-msg с помощью &lt;a href=&quot;https://www.npmjs.com/package/husky&quot; target=&quot;_blank&quot;&gt;husky&lt;/a&gt;, &lt;a href=&quot;https://www.npmjs.com/package/simple-git-hooks&quot; target=&quot;_blank&quot;&gt;simple-git-hooks&lt;/a&gt; или &lt;a href=&quot;https://www.npmjs.com/package/git-hooks&quot; target=&quot;_blank&quot;&gt;git-hooks&lt;/a&gt;.&lt;/p&gt;
  &lt;figure id=&quot;wHGo&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/d9/50/d950ad51-9671-4750-8677-b86db83f3cbe.png&quot; width=&quot;512&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;id-СоглашениеокоммитахишаблонахкМР-Мотивация&quot;&gt;Мотивация&lt;/h2&gt;
  &lt;ul id=&quot;ZM15&quot;&gt;
    &lt;li id=&quot;yie8&quot;&gt;&lt;strong&gt;Единый стиль и понятность:&lt;/strong&gt; Используя одинаковый формат коммитов, мы сделаем историю изменений более понятной. Каждый коммит будет иметь ясное обозначение типа изменения, области и краткое описание, что сразу даст представление о его смысле.&lt;/li&gt;
    &lt;li id=&quot;HOx9&quot;&gt;&lt;strong&gt;Легкость поиска и навигации:&lt;/strong&gt; Стандартизированные коммиты помогут быстрее находить связанные изменения и легче перемещаться по истории разработки. Проще отслеживать, что и когда менялось.&lt;/li&gt;
    &lt;li id=&quot;fUjJ&quot;&gt;&lt;strong&gt;Поддержка сотрудничества:&lt;/strong&gt; Благодаря четким коммитам команда будет лучше понимать, что делает каждый разработчик. Это улучшает коммуникацию и управление проектом.&lt;/li&gt;
    &lt;li id=&quot;RtOj&quot;&gt;&lt;strong&gt;Упрощение автоматизации:&lt;/strong&gt; Стандартизированные коммиты помогут автоматизировать процессы сборки, тестирования и развертывания. Меньше возможности для ошибок и быстрее выпускать новые версии.&lt;/li&gt;
    &lt;li id=&quot;iIDM&quot;&gt;&lt;strong&gt;Автоматическая документация:&lt;/strong&gt; Коммиты могут быть использованы для создания автоматической документации. Так пользователи и разработчики быстро узнают, что нового в каждой версии проекта. Можно использовать &lt;a href=&quot;https://github.com/conventional-changelog/standard-version&quot; target=&quot;_blank&quot;&gt;standard-changelog&lt;/a&gt;.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;7PAr&quot;&gt;Даже при условии сквоша коммитов в МР это полезно, потому что в истории МР будет структурированная история изменений, что упрощает код-ревью и отслеживание разработки фич. Также в Gitlab можно настроить &lt;a href=&quot;https://docs.gitlab.com/ee/user/project/merge_requests/commit_templates.html&quot; target=&quot;_blank&quot;&gt;шаблон для тела коммита.&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;uASx&quot;&gt;&lt;strong&gt;Примеры стандартов&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;cOvM&quot;&gt;
    &lt;li id=&quot;bmt6&quot;&gt;&lt;a href=&quot;https://www.conventionalcommits.org/en/v1.0.0/&quot; target=&quot;_blank&quot;&gt;Стандартная нотация&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;ARaA&quot;&gt;&lt;a href=&quot;https://www.conventionalcommits.org/en/v1.0.0-beta.4/&quot; target=&quot;_blank&quot;&gt;Angular нотация&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;4P4t&quot;&gt;Предлагаемый формат коммитов&lt;/h3&gt;
  &lt;ul id=&quot;chqO&quot;&gt;
    &lt;li id=&quot;RxUJ&quot;&gt;type(scope): subject&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;JLUi&quot;&gt;&lt;em&gt;Где:&lt;/em&gt;&lt;/p&gt;
  &lt;ul id=&quot;BssV&quot;&gt;
    &lt;li id=&quot;VJtM&quot;&gt;type — тип изменения, fix/feat/build/etc.&lt;/li&gt;
    &lt;li id=&quot;CuJc&quot;&gt;scope — область, которую затронуло изменения, либо номер заявки. Если несколько, писать через запятую. Если вне заявок, пропустить.&lt;/li&gt;
    &lt;li id=&quot;Wgkc&quot;&gt;subject — краткое описание проделанной работы. С заглавной буквы. Описание коммитов должно отвечать на вопрос: «Что делает коммит?».&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;gqh1&quot;&gt;&lt;em&gt;Тип изменения:&lt;/em&gt;&lt;/p&gt;
  &lt;ul id=&quot;QKhc&quot;&gt;
    &lt;li id=&quot;3PP5&quot;&gt;feat - используется при добавлении новой функциональности приложения&lt;/li&gt;
    &lt;li id=&quot;5SeM&quot;&gt;fix - если исправили какую-то багу&lt;/li&gt;
    &lt;li id=&quot;osjj&quot;&gt;refactor - рефакторинг кода приложения&lt;/li&gt;
    &lt;li id=&quot;bZpI&quot;&gt;style - исправляем опечатки, исправляем форматирования&lt;/li&gt;
    &lt;li id=&quot;HiU3&quot;&gt;chore - обычное обслуживание кода&lt;/li&gt;
    &lt;li id=&quot;1Q6f&quot;&gt;revert - отмена изменений&lt;/li&gt;
    &lt;li id=&quot;9mUj&quot;&gt;perf - оптимизация кода, улучшение производительности&lt;/li&gt;
    &lt;li id=&quot;XRTT&quot;&gt;docs - всё, что касается документации&lt;/li&gt;
    &lt;li id=&quot;QbFy&quot;&gt;test - всё, что связано с тестированием&lt;/li&gt;
    &lt;li id=&quot;D18f&quot;&gt;build - всё, что связано с билдом&lt;/li&gt;
    &lt;li id=&quot;okyj&quot;&gt;ci - всё, что связано с процессом деплоя&lt;/li&gt;
    &lt;li id=&quot;yQkX&quot;&gt;any - не входящее ни в одну из категорий&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;uVyg&quot;&gt;П&lt;em&gt;ример коммитов, которые пройдут проверку&lt;/em&gt;&lt;/p&gt;
  &lt;ul id=&quot;HDD1&quot;&gt;
    &lt;li id=&quot;OlJn&quot;&gt;feat(front): Внедрение проверки коммитов TASK-####&lt;/li&gt;
    &lt;li id=&quot;VIsz&quot;&gt;fix(back): Исправил дедлок в репозитории TASK-####&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;Slsd&quot;&gt;&lt;em&gt;Примеры коммитов, которые не пройдут проверку:&lt;/em&gt;&lt;/p&gt;
  &lt;ul id=&quot;HVZd&quot;&gt;
    &lt;li id=&quot;JrNE&quot;&gt;Зарефакторил компонент к заявке 35487&lt;/li&gt;
    &lt;li id=&quot;vPnu&quot;&gt;Удаление изменений по модальному окну&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;Kene&quot;&gt;Пример настройки&lt;/h3&gt;
  &lt;p id=&quot;UHk7&quot;&gt;Создать файл package.json в корне проекта (рядом с папкой .git), установить менеджер гит-хуков (&lt;a href=&quot;https://www.npmjs.com/package/husky&quot; target=&quot;_blank&quot;&gt;husky&lt;/a&gt;, &lt;a href=&quot;https://www.npmjs.com/package/simple-git-hooks&quot; target=&quot;_blank&quot;&gt;simple-git-hooks&lt;/a&gt; или &lt;a href=&quot;https://www.npmjs.com/package/git-hooks&quot; target=&quot;_blank&quot;&gt;git-hooks&lt;/a&gt;).&lt;/p&gt;
  &lt;pre id=&quot;VBWU&quot;&gt;git init
npm i @commitlint/cli @commitlint/config-conventional husky --save-dev
&lt;/pre&gt;
  &lt;p id=&quot;nGzm&quot;&gt;Добавить в секцию с хуками хук &lt;code&gt;&amp;quot;commit-msg&amp;quot;: &amp;quot;commitlint -E HUSKY_GIT_PARAMS&amp;quot;&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;B4XQ&quot;&gt;Пример package.json&lt;/p&gt;
  &lt;pre id=&quot;xOyE&quot;&gt;{
  &amp;quot;name&amp;quot;: &amp;quot;project-name&amp;quot;,
  &amp;quot;version&amp;quot;: &amp;quot;1.0.0&amp;quot;,
  &amp;quot;description&amp;quot;: &amp;quot;&amp;quot;,
  &amp;quot;husky&amp;quot;: {
    &amp;quot;hooks&amp;quot;: {
      &amp;quot;commit-msg&amp;quot;: &amp;quot;commitlint -E HUSKY_GIT_PARAMS&amp;quot;
    }
  },
  &amp;quot;devDependencies&amp;quot;: {
    &amp;quot;@commitlint/cli&amp;quot;: &amp;quot;^17.0.0&amp;quot;,
    &amp;quot;@commitlint/config-conventional&amp;quot;: &amp;quot;^17.0.0&amp;quot;,
    &amp;quot;husky&amp;quot;: &amp;quot;^8.0.0&amp;quot;
  }
}
&lt;/pre&gt;
  &lt;p id=&quot;Z87b&quot;&gt;Настроить формат коммитов в commitlint.config.js или оставить по умолчанию.&lt;/p&gt;
  &lt;pre id=&quot;w2qz&quot;&gt;module.exports = {
	extends: [&amp;#x27;@commitlint/config-conventional&amp;#x27;],
	rules: {
		&amp;#x27;body-leading-blank&amp;#x27;: [1, &amp;#x27;never&amp;#x27;],

		&amp;#x27;type-case&amp;#x27;: [2, &amp;#x27;always&amp;#x27;, &amp;#x27;lower-case&amp;#x27;],
		&amp;#x27;type-empty&amp;#x27;: [2, &amp;#x27;never&amp;#x27;],
		&amp;#x27;type-enum&amp;#x27;: [
			2,
			&amp;#x27;always&amp;#x27;,
			[
				&amp;#x27;build&amp;#x27;,
				&amp;#x27;chore&amp;#x27;,
				&amp;#x27;ci&amp;#x27;,
        			&amp;#x27;devops&amp;#x27;,
				&amp;#x27;docs&amp;#x27;,
				&amp;#x27;feat&amp;#x27;,
				&amp;#x27;fix&amp;#x27;,
				&amp;#x27;perf&amp;#x27;,
				&amp;#x27;refactor&amp;#x27;,
				&amp;#x27;revert&amp;#x27;,
				&amp;#x27;style&amp;#x27;,
				&amp;#x27;test&amp;#x27;,
				&amp;#x27;any&amp;#x27;
			]
		],

		&amp;#x27;scope-case&amp;#x27;: [2, &amp;#x27;always&amp;#x27;, &amp;#x27;lower-case&amp;#x27;],

		&amp;#x27;subject-case&amp;#x27;: [
			2,
			&amp;#x27;always&amp;#x27;,
			[&amp;#x27;sentence-case&amp;#x27;]
		],
		&amp;#x27;subject-empty&amp;#x27;: [2, &amp;#x27;never&amp;#x27;]
	}
};&lt;/pre&gt;
  &lt;h1 id=&quot;id-СоглашениеокоммитахишаблонахкМР-ШаблоныMergeRequests&quot;&gt;Шаблоны Merge Requests&lt;/h1&gt;
  &lt;p id=&quot;Bfgi&quot;&gt;Также можно добавить шаблоны к Merge Requests.  Это упростит процесс ревью и убедит всех участников, что необходимые проверки и тесты были выполнены перед слиянием&lt;/p&gt;
  &lt;h3 id=&quot;id-СоглашениеокоммитахишаблонахкМР-Мотивация.1&quot;&gt;&lt;strong&gt;Мотивация&lt;/strong&gt;&lt;/h3&gt;
  &lt;ul id=&quot;QfT9&quot;&gt;
    &lt;li id=&quot;2GPY&quot;&gt;&lt;strong&gt;Стандартизация и единообразие:&lt;/strong&gt; Шаблоны для МР позволяют установить общие стандарты и правила для всех МР в проекте. Это способствует единообразию в оформлении, структуре и требованиях к каждому МР, что облегчает их понимание и улучшает качество кода.&lt;/li&gt;
    &lt;li id=&quot;OKZG&quot;&gt;&lt;strong&gt;Улучшение коммуникации:&lt;/strong&gt; Хорошо структурированные шаблоны помогают разработчикам четко описывать суть изменений в МР. Это улучшает коммуникацию в команде и снижает возможность недопонимания.&lt;/li&gt;
    &lt;li id=&quot;S7zH&quot;&gt;&lt;strong&gt;Облегчение код-ревью:&lt;/strong&gt; Шаблоны позволяют уточнить, какой код и какой функционал должны быть протестированы перед отправкой МР на ревью. Это сокращает время, которое уходит на ревью кода, и помогает избежать пропуска критических проверок.&lt;/li&gt;
    &lt;li id=&quot;HL94&quot;&gt;&lt;strong&gt;Повышение качества кода:&lt;/strong&gt; Использование шаблонов позволяет включить в чеклист необходимые требования к коду, такие как правила форматирования, проверка наличия тестов и документации. Это способствует повышению качества кодовой базы.&lt;/li&gt;
    &lt;li id=&quot;8FDn&quot;&gt;&lt;strong&gt;Улучшение прозрачности процесса:&lt;/strong&gt; Шаблоны дают возможность ясно определить, какие шаги и требования должны быть выполнены перед слиянием МР. Это упрощает процесс слияния и делает его более прозрачным для всех участников.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;id-СоглашениеокоммитахишаблонахкМР-ШаблонМР&quot;&gt;Для Gitlab можно использовать &lt;a href=&quot;https://docs.gitlab.com/ee/user/project/description_templates.html&quot; target=&quot;_blank&quot;&gt;шаблоны МР&lt;/a&gt;. Пример файла &lt;em&gt;.gitlab/merge_request_templates/Default.md. &lt;/em&gt;Также в шаблоне настроен автоматический выбор Assignee и создание МР в Draft.&lt;/p&gt;
  &lt;pre id=&quot;Oxf3&quot;&gt;## Описание изменений

Опишите, что было сделано в этом МР.

## Чеклист

Пожалуйста, убедитесь, что все пункты ниже выполнены перед отправкой МР:
- [ ] Проставлены контексты ревью
- [ ] Добавлен Assignee
- [ ] На момент создания в МР подлит свежий develop или feature-ветка
- [ ] Все комментарии и документация актуальны и информативны
- [ ] Изменения протестированы на локальной среде разработки

Если какой-то пункт из чеклиста не выполняется, пожалуйста, исправьте это перед слиянием МР.

/assign me /draft&lt;/pre&gt;

</content></entry><entry><id>yangirov:BPMN-metadata</id><link rel="alternate" type="text/html" href="https://blog.yangirov.ru/BPMN-metadata?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=yangirov"></link><title>Метаданные и BPMN: нас просят сделать космодром, а потом не превращать задачи в космолёт</title><published>2022-02-07T16:10:34.329Z</published><updated>2022-08-23T18:08:02.784Z</updated><summary type="html">&lt;img src=&quot;https://camunda.com/wp-content/uploads/2020/06/cawemo-milestone-history-768x499.png&quot;&gt;Помните слова Германа Грефа о том что &quot;программисты не нужны&quot; и последующую статью о том как программистов пытались заменить на BPMN (Business Process Model and Notation)? Почитайте, интересная история.</summary><content type="html">
  &lt;p id=&quot;fOlV&quot;&gt;Помните слова Германа Грефа о том что &amp;quot;программисты не нужны&amp;quot; и последующую статью о том как программистов&lt;a href=&quot;https://habr.com/ru/post/510588/&quot; target=&quot;_blank&quot;&gt; пытались заменить&lt;/a&gt; на BPMN &lt;em&gt;(Business Process Model and Notation&lt;/em&gt;)? Почитайте, интересная история.&lt;/p&gt;
  &lt;p id=&quot;ioAf&quot;&gt;Мой рассказ не такой красочный, но в нем тоже есть боль, страдания, принятие и  отторжение. Выводом может быть фраза  &lt;strong&gt;&amp;quot;делай проще!&amp;quot;&lt;/strong&gt;. &lt;/p&gt;
  &lt;figure id=&quot;2zV6&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://camunda.com/wp-content/uploads/2020/06/cawemo-milestone-history-768x499.png&quot; width=&quot;768&quot; /&gt;
    &lt;figcaption&gt;Пример BPMN-системы.&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;BRXu&quot;&gt;В компании в которой я работал, решили переложить часть разработки бизнес-логики с программистов на аналитиков. &lt;/p&gt;
  &lt;p id=&quot;RmVa&quot;&gt;Сначала это были безобидные правки тарифов по ставкам. Потом решили сделать аля-BPMN, когда в визуальной среде стрелочками рисуется бизнес-логика, а потом из этого генерируется код на C# использующий под капотом процессную модель &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/framework/windows-workflow-foundation/&quot; target=&quot;_blank&quot;&gt;Windows Workflow Foundation&lt;/a&gt;.  &lt;/p&gt;
  &lt;p id=&quot;3Ltm&quot;&gt;И началось. &lt;/p&gt;
  &lt;ul id=&quot;6Uzt&quot;&gt;
    &lt;li id=&quot;5uO7&quot;&gt;Постоянные конфликты JSON-конфигураций на базе которых генерировались визуальные схемы. &lt;/li&gt;
    &lt;li id=&quot;xov8&quot;&gt;Усложнение обратной совместимости на  бекенде, потому что в кэше хранились процессы предыдущих версий. Формат контрактов так же ограничен особенностями схемы. &lt;/li&gt;
    &lt;li id=&quot;oGbg&quot;&gt;Вместо понятного SQL или C# мы писали JSON-метаданые в кастомном формате, из которых потом генерировались Entity, DTO, ViewModel, DDL-скрипты. О релевантности такого опыта на рынке даже говорить не хочется. &lt;/li&gt;
    &lt;li id=&quot;x43g&quot;&gt;Каждая новая фича давалась кровью и потом, а сроки исполнения задач росли в геометрической прогрессии. Чем естественно расстраивали менеджеров, ориентирующихся на потрясающие метрики вроде time to market, cycle time, etc.&lt;/li&gt;
    &lt;li id=&quot;0Tqy&quot;&gt;И еще миллион проблем!&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;En3W&quot;&gt;Всё получилось как в классическом примере из книги &amp;quot;Чистый код&amp;quot;, о том почему переусложненый продукт будет очень сложен в поддержке и сколько разработчиков не бери, всё равно всё будет плохо.&lt;/p&gt;
  &lt;figure id=&quot;KyuY&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f7/c1/f7c10b99-a967-4453-a7f2-5a1810cbb137.jpeg&quot; width=&quot;563&quot; /&gt;
    &lt;figcaption&gt;Ссылка на &lt;a href=&quot;https://books.google.ru/books?id=d6JSDwAAQBAJ&amp;lpg=PA1&amp;hl=ru&amp;pg=PA27#v=onepage&amp;q&amp;f=false&quot; target=&quot;_blank&quot;&gt;легендарный пример&lt;/a&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;y7BW&quot;&gt;Также из-за того что весь проект был завязан на WWF была невозможна миграция на .NET Core (смотрели форки типа &lt;a href=&quot;https://github.com/UiPath/CoreWF&quot; target=&quot;_blank&quot;&gt;CoreWF&lt;/a&gt;, но не взлетело).&lt;/p&gt;
  &lt;p id=&quot;EUts&quot;&gt;В итоге имеем сотрудников, которые работают на неактуальном стеком и изобретающими костыли для внедрения чего-либо нового где каждая задача превращается в ад.&lt;/p&gt;
  &lt;p id=&quot;UWG4&quot;&gt;К примеру, я работал над одним багом три месяца и на каждом дейли говорил &amp;quot;я в процессе, распутываю клубок&amp;quot;. Баг был в том что при нажатии на ссылку после покупки инвалидировались данные в корзине и пользователь видел ошибку. Звучит просто? Три месяца, сынок.&lt;/p&gt;
  &lt;p id=&quot;7vOr&quot;&gt;P.S. Некоторые проекты в компании отказались от использования &amp;quot;ядра&amp;quot; и начали делать простые круды с формочками на фронте. Стоит ли говорить что за несколько месяцев разработки их time-to-market уменьшился в несколько раз по сравнению с предыдущими годами?&lt;/p&gt;
  &lt;p id=&quot;MZ66&quot;&gt;P.P.S. Мой друг из крупного китайского ритейлера написал что они отказываются от метаданных. Победа здравого смысла! &lt;/p&gt;
  &lt;figure id=&quot;FVUw&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/bb/07/bb07b0c5-9132-44ac-8486-7ef892e8edc3.png&quot; width=&quot;405&quot; /&gt;
  &lt;/figure&gt;

</content></entry></feed>