私たちは、相互に依存する多くのMavenプロジェクトで構成される製品を持っています。これらすべてのMavenプロジェクトは、最終製品を提供する単一のプロジェクトにまとめられます。
Mavenプロジェクトは同じライフサイクルを共有します。言い換えると、それらは明示的な<dependency>
他のプロジェクトの新しいバージョンをピックアップするように変更。むしろ、誰かがプロジェクトの1つで何かを変更した場合、結果は追加の変更なしに直接最終製品に入るはずです。
Jenkinsを継続的インテグレーションツールとして使用します。
主な要望は次のとおりです。
pom.xml
ファイル。質問:ジェンキンスでこれを行うための最良のアプローチは何ですか?
現在、Jenkins Pipelineプラグインを使用して単一のジョブを使用することを考えています。これは、Mavenの依存関係とSCMの変更を分析し、ビルドする必要があるものとその順序を決定して、実際にプロジェクトをビルドします。
要件を達成するために、Mavenマルチモジュールビルドのデフォルト機能の多くと、以下で説明する追加の構成を利用できます。
あなたの質問から:
すべてのプロジェクト間の依存関係をJenkins構成にコピーする必要はありません。これらは単一の場所、理想的には
pom.xml
ファイル。
aggregator/multi-module pom を使用すると、Mavenビルドの単一のエントリポイント(pom.xmlファイル)を使用して、定義されたすべてのモジュールをビルドできます。
モジュールを含むプロジェクトは、マルチモジュールまたはアグリゲータープロジェクトと呼ばれます。モジュールは、このPOMがリストするプロジェクトであり、グループとして実行されます。 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
packages に注意してください。これは、このプロジェクトがpomのみを提供する(それ以上の成果物はない)ことをmavenに伝えています。
したがって、他のMavenプロジェクトをモジュールとして定義するルートMavenアグリゲータープロジェクトを作成し、このエントリポイントを構築する単一のJenkinsジョブを作成できます。
さらに、あなたの質問から:
不要なビルドを避けます。SCMの変更では、影響を受ける可能性のあるプロジェクトのみをビルドします。
この要件を満たすために、 incremental-build-plugin
:
ユニークなプロジェクトのモジュールの変更を探すため、Mavenインクリメンタルプラグインは、マルチモジュールプロジェクトでのみそれを検知します。モジュールの変更が検出された場合、出力ディレクトリは削除されます。
このプラグインは、pomファイル、リソース、ソース、テストソース、テストリソースのいずれかがモジュールで変更されるかどうか、およびケースがその出力ディレクトリを削除するかどうかを検証します。そのため、関係するモジュールのビルド時間を節約し、マルチモジュールプロジェクト全体(この場合は独自のビルド)のチェーンを節約します。
このメカニズムを有効にするには、上記のアグリゲーター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 inheritance を集約と組み合わせて使用し(従来の使用法)、マルチモジュールを持っています。ビルドと、宣言されたすべてのモジュールの共通の親によって提供される共通のビルドガバナンス(この場合、共通のビルドガバナンスは、追加のincremental-build-plugin
構成)。さらに、各モジュールはskip.incremental
プロパティは、前述のプラグインをスキップしません。これはトリックです。プラグインはルートではなくモジュールでのみ実行されます(これは意味がなく、この場合、実際にはそれ以外の場合はエラーをスローします)。
明らかに、関連するJenkinsジョブのSource Code Managementセクションでは、各ビルドの一部として新しいチェックアウトを構成する必要はありません。それ以外の場合、変更はありません。検出可能(そしてゼロから始まるたびに、これは実際にリリースビルドの良い方法です)。
さらに、mavenコマンドはclean
ライフサイクルを呼び出さないでください。これにより、ビルドごとにtarget
が削除され、変更が検出されなくなります。
さらに、あなたの質問から:
「ダイヤモンド依存関係」の場合(CはB1とB2の両方に依存し、どちらもAに依存します)、最低(A)が変更された場合、最終製品(C)は常に使用されていたバージョンのAを常に使用する必要があります。 B1とB2をビルド/テストします。
Mavenは、マルチモジュールビルドとその reactor メカニズムの一部としてこの要件を処理します。
マルチモジュールプロジェクトを処理するMavenのメカニズムは、リアクターと呼ばれます。 Mavenコアのこの部分は、次のことを行います。
- ビルドするすべての利用可能なモジュールを収集します
- プロジェクトを正しいビルド順序に並べ替えます
- 選択したプロジェクトを順番にビルドします
したがって、デフォルトでは、reactorはビルド順序も作成し、常にモジュールbeforeを依存/コンシューマーモジュールにビルドします。つまり、最後に構築されたモジュールは、実際には最終的なアーティファクトの構築を担当するモジュールであり、他のモジュールの一部またはすべてに依存する成果物(たとえば、war
ファイルの配信を担当するモジュールは、おそらく、マルチモジュールのwebappプロジェクトでビルドする最後のものです)。
Mavenおよび何かが変更されていない場合のスキップアクションに関するその他の関連資料:
maven-jar-plugin
は forceCreation
を提供します。これはデフォルトですでに有効になっていますどのコンテンツも変更されていないように見えても、新しいプラグインをビルドするためにjarプラグインが必要です。デフォルトでは、このプラグインは出力jarが存在し、入力が変更されていないかどうかを確認します。これらの条件に該当する場合、プラグインはjarの作成をスキップします。
maven-compiler-plugin
は useIncrementalCompilation
を提供しますが、現時点では 適切に機能していない です。maven-war-plugin
は recompressZippedFiles
オプションを提供します。これは、ビルドを高速化し、何かをやり直すことを回避するためにも使用できます(この場合はfalse
に切り替えます)。 :Warに追加されるZipアーカイブ(jar、Zipなど)を再度圧縮する必要があるかどうかを示します。再度圧縮すると、アーカイブサイズが小さくなりますが、実行時間が著しく長くなります。
デフォルト:true
更新
Mavenプロジェクトは同じライフサイクルを共有します。
この要件はまた、アグリゲーター/マルチモジュールプロジェクトの使用を強制しますが、実際に依存関係を通じてリンクされたさまざまなプロジェクトにも適用される場合があります。
それらは、他のプロジェクトの新しいバージョンを取得するための明示的な変更を行う個別のチームによって管理されていません。
この点は、マルチモジュールプロジェクトの使用も強制します。マルチモジュールプロジェクトでは、モジュール間でバージョンが異なる場合がありますが、一般的な慣行とガイドラインは、親プロジェクト(アグリゲーター)によって定義され、モジュール間でカスケードされた同じバージョンを共有することです。そのため、その集中化とガバナンスにより、ミスアラインメントとミスを回避できます。
誰かがプロジェクトの1つで何かを変更した場合、結果は追加の変更なしで直接最終製品に入るはずです。
繰り返しますが、これはマルチモジュールプロジェクトによって自動的に処理されます。同じことが、それぞれ SNAPSHOT versions を使用する異なるプロジェクトでも発生します。その場合、コンシューマプロジェクト(最終製品のビルドを担当するプロジェクト)の依存関係バージョンを変更する必要はありません。ただし、SNAPSHOTバージョンは開発時には非常に役立ちます(推奨されます)が、ビルドの再現性が危険になるため(つまり、後で同じバージョンを再ビルドできない場合があるため)、最終製品を提供するときには絶対に使用しないでください。スナップショットバージョンに依存していたため、フリーズバージョンではありませんでした)。したがって、SNAPSHOTは特効薬ではなく、製品のSDLCの特定のフェーズでのみ使用する必要があります。最終的な凍結溶液としては使用しないでください。
更新2
新しい Maven Incremental Module Builder Maven3.3.1 +およびJava7。
詳細: