Качество кода: SonarQube и покрытие тестами

Рейтинг: 66.7% · 13 голосов
Подробный курс по Jenkins и CI/CD: установка и настройка, плагины и Configuration as Code, конвейеры (pipeline) и Jenkinsfile, declarative и scripted, агенты, Docker и Kubernetes, общие библиотеки на Groovy, безопасность и credentials, интеграции (SonarQube, артефакты), траблшутинг. Актуально на 2026.
Ответить
Аватара пользователя
Andrey_CICD
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Качество кода: SonarQube и покрытие тестами

Сообщение Andrey_CICD »

Оглавление курса (47)
  1. Что такое Jenkins и зачем нужен CI/CD
  2. Jenkins в 2026: версии, экосистема и сравнение с GitLab CI и GitHub Actions
  3. Архитектура Jenkins: контроллер, агенты, узлы и исполнители
  4. Установка Jenkins: пакеты, Docker и Kubernetes
  5. Первичная настройка Jenkins: мастер, плагины, пользователи
  6. Плагины Jenkins: установка, обновление и ключевой набор
  7. Configuration as Code (JCasC): настройка Jenkins декларативно
  8. Конвейеры Jenkins и Jenkinsfile: pipeline as code
  9. Scripted против Declarative: два синтаксиса конвейера
  10. Структура конвейера: node, stage, steps и первый pipeline
  11. Генератор сниппетов, запуск конвейера и Replay
  12. Типы заданий Jenkins: Freestyle, Pipeline, Multibranch и Organization
  13. Декларативный конвейер: структура pipeline, agent, stages
  14. agent, environment и переменные в конвейере
  15. tools, options, parameters и triggers в декларативном конвейере
  16. stages, parallel и matrix: организация этапов
  17. Условное выполнение when и блок post
  18. Триггеры сборки: webhook от GitHub, SCM polling и расписание
  19. Параметры сборки и пользовательский ввод
  20. Управление потоком: timeout, retry, sleep и waitUntil
  21. Параллелизм и блокировки: parallel, lock, milestone
  22. Постобработка и уведомления о результате сборки
  23. Groovy для Jenkins: основы скриптового конвейера
  24. Скриптовый конвейер: логика, циклы и функции
  25. Общие библиотеки Jenkins: Shared Libraries
  26. Подключение и загрузка общих библиотек
  27. Шаги оболочки: sh, bat, powershell и коды возврата
  28. Переменные среды, withEnv и рабочие пространства
  29. Работа с файлами, артефактами и отпечатками
  30. Сборка проектов в конвейере: Maven, Gradle, npm
  31. Качество кода: SonarQube и покрытие тестами (вы здесь)
  32. Управление артефактами: публикация в Nexus и Artifactory
  33. Docker в Jenkins: образы как агенты сборки
  34. Сборка и публикация Docker-образов из конвейера
  35. Jenkins в Kubernetes: динамические pod-агенты
  36. Развёртывание в Kubernetes из конвейера
  37. Безопасность Jenkins: аутентификация и матрица прав
  38. Учётные данные Jenkins: credentials в конвейере
  39. Безопасность сценариев: Groovy sandbox и Vault
  40. Уведомления и отчёты: email, Slack, Telegram, HTML
  41. Blue Ocean и интерфейс Jenkins в 2026
  42. Автоматизация Jenkins: CLI, REST API и script console
  43. Поиск и устранение неисправностей: читаем логи конвейера
  44. Типичные ошибки конвейера: сериализация и неутверждённый код
  45. Эксплуатация Jenkins: бэкап, обновление, масштабирование
  46. Конвертация и миграция: от Freestyle к Jenkinsfile
  47. Итог: сквозной CI/CD конвейер и Jenkins против альтернатив в 2026
Сборка зелёная, тесты прошли, артефакт собрался - и ты с чистой совестью мержишь в main. А через неделю кто-то находит метод на двести строк с дублированием, проглоченным исключением и SQL-инъекцией, который тихо проехал через ревью, потому что глаза замылились. Знакомо? Проблема в том, что человек физически не способен ловить такие вещи в каждом PR на протяжении года. Машина - способна. В этом уроке мы превратим jenkins анализ кода в обязательный этап конвейера: подключим SonarQube, посчитаем покрытие тестами и сделаем так, чтобы плохой код просто НЕ ПРОПУСКАЛСЯ дальше. Не как рекомендация, а как блокирующая дверь.

Если коротко - после этого урока у тебя в pipeline появится стейдж, который может уронить сборку не из-за упавшего теста, а из-за того, что качество кода ниже порога. И это нормально.

Зачем встраивать анализ кода в CI и что такое Quality Gate

SonarQube - это сервер статического анализа. Он берёт твой исходник, гоняет по нему сотни правил (баги, уязвимости, code smells, дубли) и считает метрики: покрытие, технический долг, цикломатическую сложность. Сам по себе он полезен, но превращается в магию только когда встроен в конвейер и умеет блокировать.

Ключевое понятие здесь - Quality Gate (ворота качества). Это набор условий, которым код обязан удовлетворять. Например: "на новом коде покрытие не ниже 80 процентов", "ноль новых уязвимостей", "дублирование меньше 3 процентов". Если код проходит - ворота зелёные, конвейер едет дальше. Не проходит - красные, и связка jenkins quality gate валит сборку.

Тонкий момент, который многие упускают: современный подход - это анализ "чистого нового кода" (Clean as You Code). Не пытайся одним прыжком вылечить весь легаси - это утопия. Gate настраивается на условие "новый код" (new code), то есть на дифф твоего PR. Старый код остаётся как есть, но всё новое, что ты добавляешь, обязано быть чистым. За год проект сам собой оздоравливается без героических рефакторингов.

По состоянию на 2026 год актуальная серверная ветка - SonarQube Server 2026 (календарная нумерация вида ГГГГ.N, LTA-релиз 2026 Release 1), плюс бесплатный SonarQube Community Build (ветка 26.x). Community-редакции хватает за глаза для одного основного языка и базовых Quality Gates. Серверу нужна Java 21 как минимум - держи это в голове, если поднимаешь его рядом с Jenkins.

Изображение

Подготовка: сервер, токен и плагин SonarQube Scanner

Поднять сервер для практики проще всего в Docker:

Код: Выделить всё

docker run -d --name sonarqube \
  -p 9000:9000 \
  -v sonarqube_data:/opt/sonarqube/data \
  -v sonarqube_extensions:/opt/sonarqube/extensions \
  sonarqube:community
Заходишь на http://localhost:9000, логин admin/admin, меняешь пароль. Дальше три обязательных шага, без которых ничего не взлетит:
  • Создаёшь токен: My Account -> Security -> Generate Token. Это секрет, по которому Jenkins авторизуется на сервере.
  • В Jenkins ставишь плагин SonarQube Scanner for Jenkins. В Manage Jenkins -> System находишь блок "SonarQube servers", добавляешь сервер: имя (например MySonar), URL http://sonarqube:9000 и тот самый токен из Jenkins Credentials (тип Secret text).
  • Настраиваешь webhook на стороне SonarQube: Administration -> Configuration -> Webhooks, URL вида http://jenkins:8080/sonarqube-webhook/. Без него waitForQualityGate будет ждать вечно - именно вебхук пинает Jenkins, что анализ готов.
Последний пункт - грабли номер один. Запомни его.

Стейдж анализа в Jenkinsfile: withSonarQubeEnv и waitForQualityGate

Теперь самое интересное - declarative pipeline. Разберём связку для Java-проекта на Maven с покрытием через JaCoCo. Сначала JaCoCo считает покрытие, потом сканер отправляет данные на сервер, потом мы ждём вердикт ворот.

Код: Выделить всё

pipeline {
  agent any

  tools {
    maven 'Maven-3.9'
    jdk   'JDK-21'
  }

  stages {
    stage('Build & Test') {
      steps {
        // verify прогоняет тесты и формирует jacoco.exec + xml-отчёт
        sh 'mvn -B clean verify'
      }
      post {
        always {
          junit 'target/surefire-reports/*.xml'
        }
      }
    }

    stage('SonarQube Analysis') {
      steps {
        withSonarQubeEnv('MySonar') {
          sh '''
            mvn -B sonar:sonar \
              -Dsonar.projectKey=myapp \
              -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml
          '''
        }
      }
    }

    stage('Quality Gate') {
      steps {
        timeout(time: 10, unit: 'MINUTES') {
          waitForQualityGate abortPipeline: true
        }
      }
    }
  }
}
Что здесь происходит по шагам. withSonarQubeEnv('MySonar') - оборачивает шаг сканера, подставляет URL сервера и токен из настроек, и (важно) запоминает идентификатор задачи анализа в контексте конвейера. waitForQualityGate abortPipeline: true - ставит pipeline на паузу до прихода вебхука с результатом. Реализовано легковесно: шаг не держит агента и не долбит сервер опросом, он просто ждёт колбэк. Если ворота красные - флаг abortPipeline: true роняет сборку с FAILURE. Это и есть блокирующий этап качества.

Для не-Maven проектов (JS, Python, Go) вместо mvn sonar:sonar используют отдельный CLI sonar-scanner. Тогда в Manage Jenkins -> Tools добавляешь установку "SonarQube Scanner" и зовёшь его так:

Код: Выделить всё

stage('SonarQube Analysis') {
  steps {
    script {
      def scannerHome = tool 'SonarScanner'
      withSonarQubeEnv('MySonar') {
        sh "${scannerHome}/bin/sonar-scanner -Dsonar.projectKey=myapp"
      }
    }
  }
}
Покрытие кода и публикация HTML-отчётов

Метрика jenkins покрытие кода - это процент строк (и веток), которые реально выполнились во время прогона тестов. Для Java стандарт - JaCoCo. Связка jenkins jacoco работает так: подключаешь плагин в pom.xml, он инструментирует байткод, после прогона тестов выдаёт jacoco.xml, а SonarQube этот xml читает и показывает покрытие в своём UI.

Минимальная настройка JaCoCo в Maven:

Код: Выделить всё

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.12</version>
  <executions>
    <execution>
      <goals><goal>prepare-agent</goal></goals>
    </execution>
    <execution>
      <id>report</id>
      <phase>verify</phase>
      <goals><goal>report</goal></goals>
    </execution>
  </executions>
</plugin>
JaCoCo генерирует и человекочитаемый HTML-отчёт (target/site/jacoco/index.html). Чтобы он был доступен прямо из интерфейса сборки, используем publishHTML из HTML Publisher Plugin:

Код: Выделить всё

post {
  always {
    publishHTML(target: [
      reportName: 'Coverage Report',
      reportDir: 'target/site/jacoco',
      reportFiles: 'index.html',
      keepAll: true,
      alwaysLinkToLastBuild: true,
      allowMissing: false
    ])
  }
}
После сборки в боковом меню появится ссылка "Coverage Report". Удобно для тех, кто не хочет лезть в SonarQube ради цифры. Само число покрытия как условие Quality Gate настраивается на сервере: Quality Gates -> твой gate -> Add Condition -> Coverage on New Code is less than 80%.

Типичные грабли
  • waitForQualityGate висит до таймаута. В 99 процентах случаев - не настроен или неправильно настроен webhook на SonarQube. Проверь URL и что Jenkins вообще доступен серверу по сети (особенно если оба в Docker - имена контейнеров, а не localhost).
  • Покрытие всегда 0 процентов. Забыли прогнать тесты ДО анализа, либо не передали sonar.coverage.jacoco.xmlReportPaths, либо JaCoCo не успел сформировать отчёт. Порядок строгий: сначала verify, потом sonar:sonar.
  • Gate зелёный, хотя код плохой. Условия настроены на "Overall Code" вместо "New Code". На большом легаси старые проблемы размазываются и порог не срабатывает. Всегда вешай условия на новый код.
  • Анализ держит исполнитель. Не пихай waitForQualityGate внутрь withSonarQubeEnv или внутрь блока node без нужды - шаг ожидания не должен занимать агента. В declarative это решается отдельным stage, как в примере выше.
  • Токен в Jenkinsfile открытым текстом. Никогда. Только через Credentials и withSonarQubeEnv, который сам подставит секрет.
А как это выглядит в GitLab CI и GitHub Actions

Полезно понимать, что Jenkins тут не уникален, и идея переносима. В GitLab CI есть встроенная вкладка Code Quality и шаблон Jobs/Sonar; quality gate проверяется отдельным job, а MR блокируется через правила в настройках проекта. В GitHub Actions ставят официальный sonarqube-scan-action, а блокировку мержа делают branch protection rules с обязательной проверкой статуса. Механика везде одна: посчитать метрики -> сравнить с порогом -> не пропустить PR, если порог не взят. Jenkins даёт максимум контроля ценой того, что webhook и плагины надо настраивать руками - в облачных CI это часто из коробки.

Кстати, не строй UI вокруг Blue Ocean - в 2026 это заброшенное наследие, ему на смену давно пришёл встроенный Pipeline-граф и declarative-синтаксис.

Мини-лаба

Повтори руками, без этого тема не уляжется:
  • Подними SonarQube Community в Docker и залогинься, смени пароль.
  • Сгенерируй токен, добавь сервер в Jenkins (Manage Jenkins -> System) и настрой webhook на сервере.
  • Возьми любой Java-проект с тестами, подключи jacoco-maven-plugin, собери Jenkinsfile с тремя стейджами: Build & Test, SonarQube Analysis, Quality Gate.
  • Запусти - убедись, что покрытие появилось в SonarQube UI и отчёт виден через publishHTML.
  • Специально занизь Quality Gate (например Coverage on New Code >= 90%), добавь непокрытый метод и убедись, что сборка УПАЛА на стейдже Quality Gate. Это главное упражнение урока.
Контрольные вопросы
  • За что отвечает withSonarQubeEnv и почему нельзя просто вызвать sonar-scanner напрямую?
  • Зачем нужен webhook на стороне SonarQube и что сломается без него?
  • Что делает параметр abortPipeline: true в waitForQualityGate и в какой момент срабатывает?
  • Почему условия Quality Gate правильнее вешать на "новый код", а не на весь проект целиком?
Итог

Мы превратили качество кода из пожелания в правило. SonarQube считает баги, уязвимости и дубли, JaCoCo даёт покрытие, а связка withSonarQubeEnv + waitForQualityGate(abortPipeline: true) делает Quality Gate настоящей блокирующей дверью: плохой код не пройдёт в main, потому что pipeline просто упадёт. Подход Clean as You Code снимает страх перед легаси - чистым обязан быть только новый код. Дальше можно подключать SonarQube к проверке PR и завязывать merge на статус сборки, чтобы дверь закрывалась автоматически.
👍7 ❤️3 🔥 😄 🤔2
Аватара пользователя
oldschoolcoredump
Сообщения: 1
Зарегистрирован: 04 июн 2026, 22:54

Re: Качество кода: SonarQube и покрытие тестами

Сообщение oldschoolcoredump »

Полдня бился что waitForQualityGate висит до таймаута - оказалось ровно как тут написано, не прописал webhook на сервере. Контейнеры в docker, localhost не резолвится, надо было имя контейнера. Спасибо, сэкономил нервы.
👍1 ❤️2 🔥 😄 🤔
Аватара пользователя
sanfrancisco
Сообщения: 1
Зарегистрирован: 25 май 2026, 19:40

Re: Качество кода: SonarQube и покрытие тестами

Сообщение sanfrancisco »

А подскажите, для PR-ов лучше тот же gate на new code гонять или отдельный делать? У нас легаси огромное, на overall покрытие никогда не вытянем, хочу чтобы блокировало только новый код в мердж-реквесте.
👍1 ❤️3 🔥 😄 🤔
Ответить
← Предыдущая глава
Сборка проектов в конвейере: Maven, Gradle, npm
Следующая глава →
Управление артефактами: публикация в Nexus и Artifactory

Все главы курса «Jenkins: конвейеры CI/CD от основ до продакшена»

Поделиться темой: ✈ Telegram VK

Вернуться в «Jenkins: конвейеры CI/CD от основ до продакшена»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость