Статьи

Непрерывная доставка: статический анализ

Это третья статья в серии «Непрерывная доставка». Настройка инструментов CI завершилась тем, что Дженкинс начал работать, ожидая, пока мы его используем. Тревис, с другой стороны, остался в стороне, и скоро мы увидим, почему.

В этой статье мы рассмотрим статический анализ как первый тип задач, которые мы должны выполнить в нашем конвейере доставки. Так как это наша отправная точка, давайте рассмотрим краткое объяснение.

Статический анализ

Статический программный анализ — это анализ компьютерного программного обеспечения, который выполняется без фактического выполнения программ (анализ, выполняемый на исполняемых программах, называется динамическим анализом).

В нашем случае мы сосредоточимся на Java и трех видах анализа:

  • Checkstyle : обнаруживает нарушения правил кодирования.
  • Findbugs : ищет ошибки в скомпилированном коде Java.
  • PMD : ищет потенциальные проблемы в исходном коде Java.

Хотя мы будем использовать Java в наших примерах, та же идея применима к любому другому языку. Все три инструмента ценны и выполняют разные функции (даже при наличии перекрывающихся областей). Когда они объединены и правильно установлены, они могут обеспечить хорошую начальную оценку кода, который можно использовать, чтобы решить, стоит ли продолжать работу с остальной частью конвейера доставки. Помните: чем быстрее мы потерпим неудачу, тем быстрее мы узнаем, что исправить. По этой причине статический анализ часто является первой линией защиты. Все популярные IDE поддерживают статический анализ, поэтому во многих случаях проблемы обнаруживаются даже до того, как они попадают в такие инструменты, как Jenkins и Travis.

В более крупных проектах вы можете использовать SonarQube . Для этой статьи мы решили перейти к простому и минималистичному решению без сонара.

Checkstyle

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

Checkstyle легко настраивается и может поддерживать практически любой стандарт кодирования. Прилагается пример файла конфигурации, поддерживающего соглашения Sun Code Conventions. Кроме того, другие примеры файлов конфигурации предоставляются для других известных соглашений.

Мой опыт показывает, что в большинстве случаев требуется настройка файла конфигурации. Предопределенные правила часто являются излишними, а в некоторых случаях могут привести к потере производительности без какого-либо реального выигрыша. Однако после того, как команда настроена и начинает использовать (настраиваемый) стиль, который подходит лучше всего (часто это результат проб и ошибок типа изменений конфигурации), повышение читабельности кода становится очевидным. Находясь на «той же странице», касающейся стандарта кодирования, каждый чувствует себя более комфортно при чтении и написании кода.

FindBugs

umdfindbugs Findbugs пытается найти «известные проблемы», которые могут привести к ошибкам. В отличие от checkstyle, который я научился любить и ненавидеть, и, если что-то требует много усилий с его конфигурацией, предупреждения, создаваемые с помощью Findbugs, почти всегда являются возможными дефектами, которые могут быть в некотором роде вредными. Плюсом Findbugs является то, что он обычно находит реальные дефекты, и процент ложных срабатываний низкий. Как недостаток, ему нужен скомпилированный код. В идеале, статический анализ должен выполняться как первый шаг перед фактической компиляцией, и Findbugs заставляет нас создавать файлы классов для его запуска.

PMD

pmd_logo PMD ищет потенциальные проблемы, возможные ошибки, неиспользуемый и неоптимальный код и слишком сложные выражения в исходном коде Java. Количество реальных проблем, которые он находит, обычно немного ниже, чем у Findbugs. С другой стороны, он освещает проблемы, связанные с плохо реализованными (или удачей) лучшими практиками.

Настройка работы Дженкинс

Пришло время начать реализацию статического анализа в нашем конвейере доставки. Примеры в этой статье будут использовать исходный код, расположенный в репозитории TechnologyConversationsCD . Каталог Src содержит исходный код, скопированный с ката Tennis Game . Чтобы наша работа в Jenkins работала правильно, нам нужно будет извлечь код из репозитория, запустить статический анализ и опубликовать результаты.

Все исполнение будет выполняться Gradle . В этой статье не будут подробно рассказываться о том, как работает Gradle, и почему мы выбираем его вместо Ant, Maven и других инструментов сборки. Для получения более подробной информации, пожалуйста, посетите веб-сайт Gradle .

Начнем с установки недостающих программ и нескольких плагинов Jenkins.

докер

Dockerfile, созданный в предыдущей статье CI Tools Setup , необходимо изменить. Мы начнем с добавления клиента GIT и Gradle в наш контейнер.

[Dockerfile]

1
2
3
4
5
6
7
8
# GIT
RUN apt-get install -q -y git
 
# Gradle
ADD https://services.gradle.org/distributions/gradle-1.12-all.zip /opt/gradle-1.12-all.zip
RUN unzip /opt/gradle-1.12-all.zip -d /opt/
ENV GRADLE_HOME /opt/gradle-1.12
ENV PATH $PATH:$GRADLE_HOME/bin

Полный исходный код можно найти в Dockerfile в нашем репозитории GitHub.

После того, как все программное обеспечение установлено (GIT, Gradle, Jenkins и т. Д.), Нам нужно добавить недостающие плагины. К этому времени вы должны быть знакомы с Docker.

[Dockerfile]

1
2
3
4
5
6
7
# Jenkins: Plugins
ADD https://updates.jenkins-ci.org/latest/git.hpi /jenkins/plugins/git.hpi
ADD https://updates.jenkins-ci.org/latest/gradle.hpi /jenkins/plugins/gradle.hpi
ADD https://updates.jenkins-ci.org/latest/analysis-collector.hpi /jenkins/plugins/analysis-collector.hpi
ADD https://updates.jenkins-ci.org/latest/checkstyle.hpi /jenkins/plugins/checkstyle.hpi
ADD https://updates.jenkins-ci.org/latest/findbugs.hpi /jenkins/plugins/findbugs.hpi
ADD https://updates.jenkins-ci.org/latest/pmd.hpi /jenkins/plugins/pmd.hpi

Полный исходный код можно найти в Dockerfile в нашем репозитории GitHub.

Для краткости из этой статьи исключены некоторые другие незначительные изменения в нашем Dockerfile. Пожалуйста, получите полную копию из репо .

Как только Dockerfile был передан в GitHub и скомпилирован Docker, наш новый контейнер готов к использованию из Vagrantfile или запустив его вручную.

Чтобы перезагрузить нашу Vagrant VM, запустите следующую команду из каталога, где находится Vagrantfile:

[Vagrantfile]

1
vagrant reload --provision

Вы можете увидеть сервер Jenkins, открыв http: // localhost: 4567 в вашем любимом браузере. Наши плагины загружены и установлены (дополнительную информацию можно найти по адресу http: // localhost: 4567 / pluginManager / installer ). Вместе с GIT и Gradle, установленными на сервере, мы готовы приступить к созданию нашей первой работы.

работы

Создать новую работу Дженкинс легко. Первый пункт в левом меню — «Новый элемент». В качестве «Имя элемента» введите «myFirstJob», выберите «Создать проект программного обеспечения в свободном стиле» и нажмите кнопку «ОК». Количество задач, которые можно выполнить в работе Дженкинса, огромно. Однако мы сосредоточимся только на анализе кода. Мы сделаем следующее:

  • Вытащите код
  • Выполнить анализ
  • Опубликовать результаты

Вытащите код

jenkinsgit Выберите «GIT» в качестве «Управления исходным кодом» и добавьте свой репозиторий. Для этого упражнения вы можете использовать наше репо: https://github.com/vfarcic/TechnologyConversationsCD.git .

Далее нам нужно установить триггер, который заставит Дженкинса потянуть код. Обычно вы создаете ловушку GitHub, которая будет уведомлять ваш экземпляр Jenkins при каждом изменении содержимого репо. Однако мы будем использовать другой подход и периодически извлекать код. Причиной этой практики является то, что в настоящее время мы работаем на localhost. В производстве, пожалуйста, используйте крюки вместо натяжения, как описано ниже.

jenkinspollscm Установите «* * * * *» в разделе «Pool SCM» в «Триггерах сборки». 5 * s означает каждую минуту каждого часа или каждый день месяца каждого дня недели. Синтаксис планирования очень похож на синтаксис, используемый в Linux cron. Объяснение, предоставленное Jenkins, обычно достаточно для большинства пользователей.

Теперь у нас есть Дженкинс, тянущий GitHub каждую минуту. Если одно из этих извлечений обнаружит изменение в коде, это задание перенесет код в рабочую область. Что мы будем делать с этим кодом, будет дальше.

Выполнить задачи Gradle

Поскольку Gradle — наше предпочтительное оружие, мы будем использовать его для проведения статического анализа. Все, что нам нужно сделать, чтобы включить Checkstyle, Findbugs и PMD анализ, это добавить плагины. Вот выдержка из файла build.gradle, расположенного в корне нашего исходного кода:

1
2
3
apply plugin: 'checkstyle'
apply plugin: 'findbugs'
apply plugin: 'pmd'

Полный исходный код можно найти в build.groovy в нашем репозитории GitHub.

jenkinsgradlecheck Вот и все. Эти три строки создали новые задачи Gradle, такие как: checkstyleMain, checkstyleTest, findbugsMain и т. Д. Нам интересна задача «проверка». Он будет запускать все задачи статического анализа. На данный момент они состоят из вышеперечисленного. Больше можно добавить, просто вставив новые плагины.

Чтобы запустить задачу Gradle из Jenkins, выберите «Invoke Gradle Script» из списка «Add build step», расположенного в разделе «Build». Поскольку мы уже установили, что единственная задача, которая нам нужна, это «проверить», это именно то, что следует поставить в поле «Задачи».

Опубликовать результаты анализа

jenkinsanalysispublisher Мы почти там. Осталось только опубликовать результаты, чтобы они были легко доступны.

Чтобы опубликовать результаты Checkstyle, выберите «Опубликовать результаты анализа Checkstyle» из списка «Добавить действие после сборки». Поле «Результаты Checkstyle» должно иметь
значение «build / reports / findbugs / *. xml». Такая же настройка должна быть повторена для Findbugs и PMD. Проверьте параметры, скрытые за кнопкой «Дополнительно», особенно «Пороги состояния». Вероятно, наиболее важным параметром в разделе «Дополнительно» является флажок «Всегда запускать». Без этого издатели запускаются только при отсутствии предупреждений статического анализа.

Запустить работу

Теперь у нас все установлено, и единственное, чего не хватает, это запустить работу. Мы уже установили задание на выполнение при каждом изменении нашего GIT-репозитория. Работа Дженкинса будет запущена вскоре после нашего следующего толчка. Если этого недостаточно, вы можете запустить любое задание, перейдя к заданию и щелкнув ссылку «Построить сейчас», расположенную в левой части экрана. Новая сборка начнется. Когда все будет готово, отчеты Checkstyle, Findbugs и PMD будут размещены внутри результата сборки.

Сводка настроек работы Дженкинса

На первый взгляд все эти шаги могут показаться пугающими. Однако, немного потренировавшись, процесс не должен занимать более 15 минут. Мы сделали следующее:

  • Изменен Dockerfile для включения инструкций по установке Gradle и GIT.
  • Изменен Dockerfile для загрузки необходимых плагинов Jenkins.
  • Перезагрузил наш Vagrant VM
  • Создано новое задание Jenkins, которое извлекает код из нашего GIT-репозитория, запускает задачу проверки из нашего скрипта сборки Gradle и, наконец, публикует результаты.

Это только начало. На нашем пути к непрерывной доставке осталось много других шагов и концепций. Некоторые из них будут рассмотрены в следующей статье. Прямо сейчас мы переключим наше внимание на Travis и посмотрим, как мы можем сделать то же самое (или подобное), используя облачное решение.

Travis

Трэвис-логотип Как вы вскоре увидите, Travis (по крайней мере, облачная версия) требует гораздо меньше работы, чем локальный экземпляр Jenkins. Как правило, все, что нам нужно сделать, чтобы использовать Travis (помимо регистрации), это:

  • Включить сборки из репозитория GitHub
  • Создайте файл .travis.yml с инструкциями

Включить сборку из репозитория GITHub

Трэвис работает только с репозиториями GIT. Вы можете раскошелиться на тот, который мы использовали в этой статье. Если вы никогда не разыгрывали репозиторий GITHub, выполните следующие инструкции:

  • Перейти к TechnologyConversationsCD
  • Нажмите на значок «Вилка» в правом верхнем углу страницы.

travisrepositories Предполагая, что вы уже вошли в систему, чтобы включить процесс сборки для некоторого репозитория GITHub, нажмите «Учетные записи» под своим именем. На следующем экране должны быть перечислены все репозитории, которыми вы владеете, и, если вы разветвили репозиторий компакт-дисков, он должен быть в списке. Включи это.

Сам разветвленный репозиторий уже поставляется с .travis.yml. Полный файл очень короткий.

[.Travis.yml]

01
02
03
04
05
06
07
08
09
10
11
language: java
 
before_install:
  - chmod +x gradlew
 
env:
  - TERM=dumb
 
notifications:
  email:

Полный исходный код можно найти в .travis.yml в нашем репозитории GitHub (и тот, который вы только что раздвоили).

Первое, что вы можете заметить, это то, что, в отличие от Дженкинса, нам не нужно указывать Трэвису, что делать. Он достаточно умен, чтобы понять это сам. Нам просто нужно указать несколько вещей, таких как, например, уведомления по электронной почте, которые будут использоваться. Как правило, Трэвис требует от нас указывать нестандартные вещи, те, которые он сам не может понять. Если проект выполнен с использованием какого-то стандарта (как в случае с примером кода, который мы используем), Travis вполне способен знать, что делать. В этом случае он, среди прочего, будет запускать «проверку» задачи Gradle так же, как это делал Дженкинс. Если в какой-либо части процесса сборки произошел сбой, Travis остановит выполнение и уведомит нас по электронной почте (или любым другим способом связи, который мы указали).

Вот и все. Нам почти ничего не нужно было делать, чтобы статический анализ нашего примера кода работал в Travis. Простой файл .travis.yml — это все, что нужно. Одним из больших преимуществ является то, что файл конфигурации хранится вместе с остальной частью нашего кода. Это значительно упрощает хранение и обслуживание.

Основным недостатком Travis является то, что единственным результатом (без каких-либо «взломов») является вывод журнала. Там нет хороших отчетов, как те, которые подготовил Дженкинс. Это не обязательно должно быть плохо. Общая идея непрерывной интеграции, развертывания и доставки заключается в том, что никакие новости не являются хорошими новостями. Если это не терпит неудачу, игнорируйте это. Другим важным фактором являются очень короткие циклы. В то же время должно быть очень мало сбоев, и приоритет должен состоять в том, чтобы исправить их, прежде чем команда продолжит работу. Выполнение этих двух вещей (действия только в случае неудачи и коротких циклов) в большинстве случаев не требует «причудливых» отчетов. Однако для достижения этой цели может потребоваться много времени, и многим организациям потребуется, чтобы вы предприняли промежуточные шаги, подготовили отчеты … Если это так, то Дженкинс, вероятно, является лучшим вариантом. В моем случае я использую оба, но если бы мне пришлось выбирать только один, это был бы Трэвис.

Другие инструменты

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

Drone.io

Иностранец-зап-заголовок Drone.io — интересный инструмент. В некоторых аспектах он похож на Travis. В других это склоняется к Дженкинс. Лучший пример — конфигурация.

  • Travis использует простой файл для всех настроек, и этот файл является частью вашего кода.
  • Jenkins предлагает бесконечные возможности через систему плагинов. Цена за это может быть увеличена за время, необходимое для настройки и администрирования.
  • Drone.io не является ни тем, ни другим. Здесь нет файла конфигурации, как в Travis, и нет бесконечных возможностей, как в случае с Jenkins. Конфигурация выполняется с помощью веб-интерфейса Drone.io. Это простой в использовании интерфейс, подобный мастеру, который оставляет желать лучшего.

И Трэвис, и Дженкинс предлагают очень мощные, но разные способы настройки заданий. Drone.io использует интересную концепцию, которая все еще требует полировки, прежде чем он станет серьезным конкурентом в топ-листе инструментов CI / CD. Например, нет очевидного способа использовать Gradle в проекте Java. Как только он был установлен как Groovy, он работал.

Будет интересно увидеть прогресс Drone.io в ближайшие месяцы.

BuildHive

BuildHive является одним из многих облачных сервисов CI. Он построен на вершине Дженкинс. Идея сама по себе очень интересная. Jenkins в облаке может быть переведен как мощность без хлопот, связанных с обслуживанием вашего локального сервера. Однако, BuildHive имеет всю эту мощь, урезанную. Пользователи остаются без вещей, которые им нравятся больше всего о Jenkins (плагины и бесконечные возможности), с небольшим взамен. Может быть, это нечто большее, чем кажется на первый взгляд, но для меня это был очень разочаровывающий опыт.

Круг

circleci Круг было так же легко начать использовать, как и Трэвис. Выберите репо и все. Сборка была выполнена без проблем. Как и в случае с travis, дополнительную настройку можно выполнить с помощью файла circle.yml, который находится в корне хранилища. Пожалуйста, посмотрите на circle.yml, который использовался с кодом из этой статьи. В качестве дополнительной опции, есть веб-интерфейс, который позволяет настраивать без создания файла circle.yml.

Первое, что я заметил, когда Circle работает в репозитории, используемом в этой статье, это скорость. Это было значительно быстрее, чем Трэвис. Однако это само по себе мало что говорит, потому что код состоит только из двух классов и нескольких зависимостей. Итак, я попробовал это с большим большим проектом (Scala, Play, AngularJS, более чем несколько зависимостей …). Результаты были неутешительными. Первый запуск был значительно медленнее, чем Трэвис. Это было как-то не понятно, что делать с зависимостями, он повторял один и тот же длительный процесс извлечения зависимостей несколько раз, путался с тестами Play и SBT и запускал один и тот же набор дважды и т. Д. Это был очень болезненный опыт, который закончился после 29 минут или, примерно, в 5-7 раз медленнее, чем Трэвис (тот же процесс обычно занимает около 4-6 минут). Я мог только предположить, что комбинация Scala / Play — это не то, что любит Circle. Однако вскоре после этого я связался с Серкл, объяснил проблему и быстро ее исправил. С этого момента время выполнения проекта сократилось с 29 до 2-3 минут, или примерно половины Трэвиса.

Другим недостатком является то, что, за исключением 14-дневного пробного периода, для проектов OSS нет бесплатного сервиса, как в случае с Travis.

Для желающих заплатить Circle — отличная альтернатива Travis. Он использует те же принципы, он гораздо быстрее и имеет действительно отличную поддержку клиентов.

Резюме

Мы настраиваем статический анализ на Дженкинса и Тревиса. Трэвис оказался намного проще в настройке, в то время как Jenkins сиял своими плагинами и веб-интерфейсом. Оба инструмента предлагают мощные (но очень разные) способы настройки вашей работы.

В следующих статьях будет представлена ​​более подробная информация о процессе непрерывной интеграции и доставки. Далее в нашем списке находятся тесты и покрытие кода.

Мы добавим Circle к существующему набору инструментов. Все примеры будут выполнены с использованием Jenkins (локальный сервер), Travis (облако) и Circle (облако). Пожалуйста, дайте мне знать, если вы считаете, что было бы неплохо изучить дополнительные инструменты.