21

相互に依存する多くの Maven プロジェクトで構成される製品があります。これらのすべての Maven プロジェクトは、最終製品を提供する単一のプロジェクトにまとめられます。

Maven プロジェクトは同じライフサイクルを共有します。<dependency>つまり、他のプロジェクトの新しいバージョンを取得するために明示的な変更を行った別のチームによって管理されることはありません。むしろ、誰かがプロジェクトの 1 つで何かを変更した場合、その結果は追加の変更なしで最終製品に直接反映される必要があります。

Jenkins を継続的インテグレーション ツールとして使用しています。

主なお願いは以下の通りです。

  • プロジェクト間のすべての依存関係を Jenkins 構成にコピーする必要はありません。これらは 1 つの場所、理想的にはpom.xmlファイルにある必要があります。
  • 不必要なビルドを避ける: SCM の変更時には、影響を受ける可能性のあるプロジェクトのみをビルドします。
  • ひし形の依存関係(C は A に依存する B1 と B2 の両方に依存する) の場合、最低 (A) が変更された場合、最終製品 (C) はビルドにも使用された A のバージョンを常に使用する必要があります。 / B1 と B2 をテストします。

質問: Jenkins でこれを行う最善の方法は何ですか?

現在、Maven の依存関係と SCM の変更を分析し、何をどの順序でビルドする必要があるかを判断し、実際にプロジェクトをビルドする Jenkins Pipeline プラグインを使用する単一のジョブを使用することを考えています。

4

1 に答える 1

27

要件を達成するために、maven マルチモジュール ビルドのデフォルト機能の多くと、以下で説明する追加の構成に依存できます。

あなたの質問から:

プロジェクト間のすべての依存関係を Jenkins 構成にコピーする必要はありません。これらは 1 つの場所、理想的にはpom.xmlファイルにある必要があります。

アグリゲーター/マルチモジュール 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パッケージングに注意してください。これは、このプロジェクトがpomのみを提供することをmavenに伝えています(それ以上のアーティファクトはありません)。

したがって、他の Maven プロジェクトをモジュールとして定義し、このエントリ ポイントを構築する単一の Jenkins ジョブを持つルート Maven アグリゲータ プロジェクトを作成できます。


さらに、あなたの質問から:

不必要なビルドを避ける: SCM の変更時には、影響を受ける可能性のあるプロジェクトのみをビルドします。

この要件を満たすには、次を使用できますincremental-build-plugin

固有のプロジェクトのモジュールの変更を探すため、Maven Incremental Plugin はマルチ モジュール プロジェクトでのみそれを認識します。モジュールの変更が検出された場合、出力ディレクトリは削除されます。

このプラグインは、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 継承をアグリゲーションと組み合わせて使用​​し (従来の使用法)、マルチモジュール ビルドと共通ビルド ガバナンスが提供されています。宣言されたすべてのモジュールの共通の親によって (この場合、共通のビルド ガバナンスによって追加のincremental-build-plugin構成が提供されます)。skip.incrementalさらに、各モジュールは、前述のプラグインをスキップしないようにプロパティを再構成します。これはトリックです: これで、プラグインはそのルートではなく、モジュールでのみ実行されます (これは意味がなく、この場合、実際にはエラーがスローされます)。

明らかに、関連する Jenkins ジョブのソース コード管理セクションでは、各ビルドの一部として新しいチェックアウトを構成する必要はありません。実際にはリリースビルドの良い習慣です)。

さらに、maven コマンドはライフサイクルを呼び出すべきではありません。これにより、ビルドごとcleanに も削除され、変更が検出されなくなります。target


さらに、あなたの質問から:

「ひし形の依存関係」 (C は B1 と B2 の両方に依存し、どちらも A に依存する) の場合、最低 (A) が変更された場合、最終製品 (C) は常に、使用された A のバージョンを使用する必要があります。 B1 と B2 をビルド/テストします。

Maven は、マルチモジュール ビルドとそのリアクターメカニズムの一部として、この要件を処理します。

マルチモジュール プロジェクトを処理する Maven のメカニズムは、reactor と呼ばれます。Maven コアのこの部分は、次のことを行います。

  • ビルドするために利用可能なすべてのモジュールを収集します
  • プロジェクトを正しいビルド順序に並べ替えます
  • 選択したプロジェクトを順番にビルドします

したがって、デフォルトでは、reactor もビルド順序を作成し、常に依存モジュール/消費者モジュールの前にモジュールをビルドします。これはまた、最後にビルドされたモジュールが実際には最終的なアーティファクトのビルドを担当するモジュールになることを意味し、成果物は他のモジュールの一部またはすべてに依存します (たとえば、warファイルの配信を担当するモジュールは、おそらく最後にマルチモジュール webapp プロジェクトでビルドします)。


何かが変更されていない場合の Maven およびスキップ アクションに関するその他の関連資料:

  • は、デフォルトですでに有効になって いる をmaven-jar-plugin提供しますforceCreation

    コンテンツがまったく変更されていないように見える場合でも、jar プラグインが新しい JAR を構築する必要があります。デフォルトでは、このプラグインは、出力 jar が存在し、入力が変更されていないかどうかを確認します。これらの条件が true の場合、プラグインは jar の作成をスキップします。

  • maven-compiler-pluginを提供しますが、現時点では適切に機能してuseIncrementalCompilationいません。
  • は、ビルドを高速化し、何かをやり直すのを避けるためにも使用できるオプションをmaven-war-plugin提供します (この場合はに切り替えるため): recompressZippedFilesfalse

    war に追加される zip アーカイブ (jar、zip など) を再度圧縮する必要があるかどうかを示します。再度圧縮すると、アーカイブ サイズが小さくなる可能性がありますが、実行時間が著しく長くなります。
    デフォルト:true


アップデート

Maven プロジェクトは同じライフサイクルを共有します。

この要件は、アグリゲーター/マルチモジュール プロジェクトの使用も強制しますが、依存関係を介してリンクされたさまざまなプロジェクトにも適用される場合があります。

他のプロジェクトの新しいバージョンを取得するために明示的な変更を行った別のチームによって管理されることはありません。

この時点で、マルチモジュール プロジェクトの使用も強制されます。マルチモジュール プロジェクトでは、モジュール間でバージョンが異なる場合がありますが、親プロジェクト (アグリゲーター) によって定義され、そのモジュール間でカスケードされた同じバージョンを共有することが一般的な方法とガイドラインです。そのため、その集中化とガバナンスにより、不一致や間違いが回避されます。

誰かがプロジェクトの 1 つで何かを変更した場合、その結果は、追加の変更なしで最終製品に直接反映される必要があります。

繰り返しますが、これはマルチモジュール プロジェクトによって自動的に処理されます。それぞれがSNAPSHOT バージョンを使用する異なるプロジェクトでも同じことが起こります。その場合、そのコンシューマー プロジェクト (最終製品のビルドを担当するプロジェクト) で依存関係のバージョンを変更する必要はありません。ただし、SNAPSHOT バージョンは開発中に非常に役立ちます (そして推奨されます) が、ビルドの再現性が危険にさらされるため (つまり、後で同じバージョンを再ビルドできない可能性があるため)、最終製品を提供するときに絶対に使用しないでください。 SNAPSHOT バージョンに依存していたため、凍結されたバージョンではありません)。したがって、SNAPSHOT は特効薬のソリューションではなく、製品の SDLC の特定の段階でのみ使用する必要があり、最終化および凍結されたソリューションとしては使用しないでください。


Update 2 Maven 3.3.1+および Java 7
用 の新しいMaven Incremental Module Builderも検討する価値があります。

詳細:

于 2016-04-25T20:51:47.733 に答える