Ответ 1
Для достижения ваших требований вы можете опираться на многие из стандартных функций многомодовой сборки maven и дополнительную конфигурацию, описанную ниже.
Из вашего вопроса:
Не нужно копировать все межпроектные зависимости в конфигурацию Jenkins: они должны находиться в одном месте, в идеале - в файлах
pom.xml
.
Используя aggregator/multi-module pom, вы можете иметь единственную точку входа (файл pom.xml) для сборки maven, которая затем создайте все определенные модули:
Проект с модулями известен как многомодульный или агрегаторный проект. Модули - это проекты, которые этот POM перечисляет и выполняется как группа. Проект с пакетной компоновкой может объединять сборку проектов, перечисляя их как модули, которые являются относительными каталогами для этих проектов.
То есть, файл pom.xml
выглядит следующим образом:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>module-1</module>
<module>module-2</module>
<module>module-n</module>
</modules>
</project>
Является минимальным примером: определите список модулей (другие проекты maven), которые будут созданы, начиная с этого проекта maven (пустой проект, целью которого является создание других проектов maven). Обратите внимание на pom
упаковку, требуемую для модулей, сообщая maven, что этот проект предоставляет только pom (никаких дополнительных артефактов).
Таким образом, у вас может быть корневой проект агрегатора Maven, который будет определять другие проекты maven в качестве своих модулей и иметь одно задание Jenkins, создающее эту точку входа.
Кроме того, из вашего вопроса:
Избегайте ненужных сборок: при изменении SCM создавайте только потенциально затронутые проекты.
Чтобы выполнить это требование, вы можете использовать incremental-build-plugin
:
Поскольку он ищет модификацию модулей уникального проекта, Maven Incremental Plugin воспринимает его только в проектах с несколькими модулями. Если обнаружено изменение в модуле, выходной каталог удаляется.
Этот плагин проверяет, будет ли какой-либо из pom файла, ресурсов, источников, источников тестов, тестовых ресурсов изменяться в модуле, и если случай удалит его выходной каталог. Таким образом, экономия времени сборки для соответствующего модуля и цепочки для всего мультимодульного проекта (в этом случае наша собственная сборка).
Чтобы включить этот механизм, вы можете настроить в вышеупомненном агрегаторе следующее:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>module-1</module>
<module>module-2</module>
<module>module-n</module>
</modules>
<properties>
<skip.incremental>true</skip.incremental>
</properties>
<build>
<plugins>
<plugin>
<groupId>net.java.maven-incremental-build</groupId>
<artifactId>incremental-build-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<goals>
<goal>incremental-build</goal>
</goals>
<configuration>
<noIncrementalBuild>${skip.incremental}</noIncrementalBuild>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Выше мы просто добавили incremental-build-plugin
в сборку агрегатора и свойство skip.incremental
, которое пропустит выполнение плагина для первой сборки, пустой агрегатор, включив ее в модули следующим образом:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sample</groupId>
<artifactId>project</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>simple-module</artifactId>
<properties>
<skip.incremental>false</skip.incremental>
</properties>
</project>
Примечание: в pom выше примерного модуля мы указываем на файл pom агрегатора как родительский, следовательно, используя наследование maven в комбинации с агрегацией (классическое использование) и, как таковая, с многомодульной сборкой плюс общее управление построением, предоставляемое общим родителем для всех объявленных модулей (в этом случае общее управление построением обеспечивает дополнительную конфигурацию incremental-build-plugin
). Кроме того, каждый модуль перенастраивает свойство skip.incremental
, чтобы не пропускать вышеупомянутый плагин. Это трюк: теперь плагин будет выполняться только в модулях, а не в его корне (что бы не имело смысла и в этом случае фактически выдавало бы ошибку в противном случае).
Очевидно, что в связанном задании Дженкинса в разделе "Управление исходным кодом" нам не нужно настраивать новую новую проверку как часть каждой сборки, иначе никакие изменения не будут обнаружены (и каждый раз, когда она начиналась с нуля, что является хорошей практикой для релизов на самом деле).
Кроме того, ваша команда maven не должна вызывать жизненный цикл clean
, который также удаляет target
в каждой сборке и, как таковой, также не может обнаруживать изменения.
Кроме того, из вашего вопроса:
В случае "алмазных зависимостей" (C зависит как от B1, так и от B2, которые оба зависят от A), если нижний (A) изменяется, то конечный продукт (C) всегда должен использовать версию A, которая был также использован для построения/тестирования B1 и B2.
Maven позаботится об этом требовании как часть многомодульной сборки и ее механизм :
Механизм в Maven, который обрабатывает многомодульные проекты, называется реактором. Эта часть ядра Maven делает следующее:
- Собирает все доступные модули для сборки
- Сортирует проекты в правильный порядок сборки
- Создает выбранные проекты в порядке
По умолчанию реактор также создаст порядок сборки и всегда будет создавать модуль до своего зависимого/потребительского модуля. Это также означает, что последний построенный модуль фактически будет модулем, ответственным за создание финального артефакта, поставляемого продукта в зависимости от части или всех других модулей (например, модуль, ответственный за доставку файла war
, вероятно, будет последний, чтобы построить в мультимодульном проекте webapp).
Дальнейшее родственное чтение относительно Maven и пропустить действия, когда что-то не изменилось:
-
maven-jar-plugin
предоставляетforceCreation
который по умолчанию уже включенТребовать, чтобы плагин jar создавал новый JAR, даже если ни одно из содержимого не изменилось. По умолчанию этот плагин смотрит, существует ли выходной банд, и входы не изменились. Если эти условия верны, плагин пропускает создание банки.
-
maven-compiler-plugin
предоставляетuseIncrementalCompilation
, хотя не работает должным образом на данный момент. -
maven-war-plugin
предоставляетrecompressZippedFiles
который также может быть использован для ускорения сборки и предотвращения повторного выполнения чего-либо (чтобы переключиться наfalse
в этом случае):Указывает, должны ли быть сжаты архивы zip (jar, zip и т.д.), добавленные к войне. Сжатие снова может привести к меньшему размеру архива, но значительно увеличивает время выполнения.
По умолчанию:true
Обновить
Проекты Maven имеют один и тот же жизненный цикл.
Это требование также обеспечит использование проекта агрегатора/мультимодуля, но может также применяться к различным проектам, связанным через зависимости.
они не управляются отдельными группами людей с явными изменениями для поиска новых версий других проектов.
Этот момент также предусматривает использование многомодульного проекта. В многомодульном проекте у вас могут быть разные версии среди модулей, однако распространенная практика и рекомендация - использовать одну и ту же версию, определенную родительским проектом (агрегатором) и каскадированную через его модули. Таким образом, его централизация и управление позволят избежать несоосности и ошибок.
когда кто-то что-то изменяет в одном из проектов, результат должен перейти непосредственно в конечный продукт без дополнительных изменений.
Опять же, это будет автоматически обрабатываться многомодульным проектом. То же самое произойдет с разными проектами, каждый из которых использует версии SNAPSHOT, тогда нет необходимости менять версию зависимостей в своем потребительском проекте (тот, кто отвечает за создание конечного продукта). Тем не менее, хотя версии SNAPSHOT действительно полезны (и рекомендуются) во время разработки, они, безусловно, не должны использоваться при доставке конечного продукта, поскольку воспроизводство сборки будет в опасности (то есть вы не сможете повторно построить ту же версию позже поскольку он полагался на версии SNAPSHOT, следовательно, не замороженные версии). Следовательно, SNAPSHOT не является решением для серебряных пулей и должен использоваться только на определенных этапах SDLC продукта, а не в качестве окончательного и замороженного решения.
Обновление 2
Стоит также взглянуть на новый Maven Incremental Module Builder для Maven 3.3.1 + и Java 7.
Подробнее о: