Почему я плагин для Maven писал

в 6:47, , рубрики: java, maven, plugin

image

Все началась, когда я поменял работу и сходу попал на большой проект. Большой для меня это несколько вендоров, десяток систем, 5-ти ступенчатый релизный цикл, 1000К+ инженеров в разных локациях. Исходники «жили» в нескольких svn репозиториях с большим количеством maven модулей, каждый из которых мог использоваться в одной или нескольких системах. Каждый модуль был подключен в основную систему через бинарную зависимость. В конце релизного цикла необходимо было выпустить новые версии модулей и собранных на их основе систем. Под катом я опишу проблему эффективности этого процесса, с которой я попытался побороться — и что из этого вышло.

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

Пример, как все работало на нашем проекте:

  • Есть модули A, B, C и 2 системы X, Y;
  • X собирается из A (версия 1.0.0), B (1.1.0);
  • Y Собирается из B (1.8.0), C(1.0.0);
  • Модуль B может зависеть, например, от А;
  • Зависимости прописаны в корневых pom.xml каждой из систем, как бинарные (смотрите ниже);
  • В конце цикла разработки необходимо: выпустить релиз изменившихся модулей и новые версии X и Y (увеличить версию).
	<dependencies>
	      <dependency>
	        <groupId>B</groupId>
	        <artifactId>B</artifactId>
	        <version>1.1.0</version>
	      </dependency>
Проблема

  • Есть люди, ответственные за релиз каждой системы. Соответственно, они были вынуждены в конце каждого релизного цикла (1 месяц) искать все изменения по всем модулям, новые версии которых должны были войти в релиз и после этого выпускать новые релизы изменившихся модулей и в правильной последовательности (см п.4 примера), обновить <dependencies> секцию корневого pom.xml своей системы ссылками на свеженькие версии выпущенных модулей;
  • Модулей действительно много, некоторые менялись, некоторые – нет;
  • Инженеров тоже много и узнать, нужны ли изменения отдельно взятого модуля в системе X и Y обычно можно только с помощью человека, который делал эти изменения, и его начальника.
Как решали

Процесс полностью автоматизировать не получится, так как не хватает информации, какую версию зависимости нужно поставить в релизе системы. Ну, делаем что можем — на Python был написан скрипт, который выводил все зависимости, в которых были сделаны хоть какие-либо изменения за прошедший релизный период. Дальше этот список распределялся среди безответственных инженеров, которые «не сильно заняты в данный момент», каждый из которых для своей части:

  1. Находил где «живет» модуль в svn, смотрел последние изменения за период;
  2. Связывался с тем, кто туда комитил дабы узнать нужно/можно ли релизить или «подожди еще чуть-чуть я баг закрою»;
  3. С помощью release плагина к maven создавал новую версию, ветку в svn, обновлял версию в pom.xml.

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

  • Используется кастомный скрипт, который, как я позже узнал у людей, его использующих, не читал значения из <scm> тега, а держал ссылки каждого модуля на его SVN_URL в текстовом файле;
  • Так же скрипт выводил плоский список, а не дерево зависимостей. Дерево поможет определить, в какой последовательности нужно релизить артефакты;
  • Не выводил авторов последних комитов, что могло помочь в распределении, кто же будет релизить модуль.

Первая мысль была тогда – «Зачем писать кастомное, если все есть в maven?»

Maven

Постановка задачи: написать плагин под Maven, который покажет дерево зависимостей всех модулей с информацией о его текущей версии и логом последнего комита за определенный период.

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

Как он работает:

  1. Использует Dependency tree builder из maven dependency plugin;
  2. Для каждого модуля из дерева строит описание Maven проекта в памяти. Описание проекта берет либо с локального pom.xml или из Maven репозитория;
  3. Читает <scm><connection> информацию для каждого проекта. Если в текущем pom.xml эта информация отсутствует, то смотрит родительский проект.
  4. Используя SCM Maven provider и информацию, полученную на предыдущем шаге, получает список изменений за указанный период;
  5. Выводит все в удобочитаемом виде в файл.
Заключение

Получилось довольно просто. Ссылка на исходники https://github.com/temas-hub/changed-maven-plugin и там же — как им пользоваться. Буду рад, вопросам и замечаниям. Надеюсь, кто-то найдет эту статью полезной.

Автор: temas

Источник

* - обязательные к заполнению поля