2

I currently have a large number of projects with a complex dependency structure being developed by 50+ developers using Maven 2/3 with Nexus and Jenkins. We develop at a fast pace and more often that not we build and deploy releases with SNAPSHOT dependencies. Most of the time we cannot wait for one team or another to build a release version before we have to deploy. Due to this we have had a number of issues with bugs and works-in-process entering production and having no idea what changes are in those SNAPSHOTS.

What I am looking to do is to eliminate SNAPSHOTS and move to automatic releases with the versions-maven-plugin and to implement a release Staging policy.

And here in lays the problem. For developers and for the CI build it needs to be configured to resolve dependencies from "Staging" and "Release" and publish ONLY to "Staging". We then want to be able to "Promote" that build as a release, re-building it to resolve dependencies from "Release" and publish to "Release" (initially this will be a manual promotion but we may wish to automate this also). Does this all sound reasonable?

I do not want to use the maven-release-plugin because we have tried to use this before and we don't like the fact that it modifies the pom automatically and makes changes in our scm, triggering more builds.

Also, is there even a way to tell maven to use one repository for resolving and another to publish to? Could I do this with gradle?

Any comments/ideas on this would be greatly appreciated.

4

3 に答える 3

3

私のビルドシステムによく似ています。

これは、gradle と 2 つの個別の nexus リポジトリ (「リリース」リポジトリ、1 つのステージングと 1 つの最終リポジトリ) を使用して行います。ビルドにはターゲット成熟度の概念があり、これを使用して (セマンティック バージョニングを使用して) バージョン番号を計算するため、RC ビルドは 1.0.0-rc1 のようなバージョンを生成し、最終ビルドは 1.0.0 のようなバージョンを生成します。次に、テストのさまざまなスライスがさまざまな時間に実行されるように、さまざまな方法でタグ付けされたテスト (testng グループ、cucumber タグなど) を用意します。ビルドは、ターゲットの成熟度に基づいて依存または公開するリポジトリを決定するため、十分に成熟したアーティファクトのみが消費されるようにすることができます。

これは teamcity ビルド チェーンを介して自動的に実行されるように構成されているため、必要に応じて一部のコア lib のコミットがダウンストリーム ビルドを介して統合テスト/デプロイ (一連の gradle タスクによる Java API を介した rundeck による) に波及します。

Gradle の公開リポジトリと解決リポジトリは別々に構成されているため、異なる場合があります。Mavenでも同じことができます。

たとえば、次のような依存関係グラフがあるとします。

corelib -> mylib -> myapp

それぞれに、beta または rc としてタグ付けされた一連のテストが関連付けられます。RC を生成するビルドは、ベータ テストに合格したビルド (つまり、ベータに合格した場合は、RC になるのに十分成熟したビルド) であり、そのビルドはすぐに終了するビルドです (たとえば、単体テストのみを実行します)。一方、(最終ビルドを生成する) rc テストは、いくつかの統合テストまたはより長時間実行されるテストを実行する場合があります。この定義は私たち自身のものであり、完全に恣意的なものです。好きなように区別することができます。私たちのテストは、製品に一定の信頼レベルがある場合にのみ、ますます厳格化および/または長期的なテストを適用することに基づいています.

次に、ビルド チェーンをセットアップして、rc ビルドが上流の rc ビルドに依存し、最終ビルドが上流の最終ビルドと独自の rc ビルドに依存するようにします。

すなわち

             --> mylib final --
           /                   \
mylib rc --                     --> myapp final
           \                   /
             --> myapp rc -----

等々。この例では、フローは次のとおりです。

  • mylib への変更をコミットする
  • mylib rc ビルドが実行されます
    • ベータテストを実行します
    • 結果を rc リポジトリに公開する
  • mylib final と myapp rc は並行して実行できます
  • mylib 最終ビルドの実行
    • rc テストを実行します
    • 結果を最終リポジトリに公開する
  • myapp rc ビルドが実行されます
    • rc リポジトリに依存するため、以前の mylib rc ビルドの結果を取得します
    • ベータテストを実行します
  • myapp 最終実行
    • 最終リポジトリに依存するため、以前の mylib 最終ビルドの結果を取得します
    • rc テストを実行します

各ポイントのバージョン番号は、ソース管理を調べることによって計算されます

私たち自身のアーティファクトへの依存関係は動的であり (たとえば、ivy 用語で 1.0.+)、major.minor は静的に (ソース管理で) 設定され、ビルドはパッチと候補番号自体を生成するために残されます。つまり、myapp 1.0 は依存しますmylib 1.0.+ . IMO では、gradle/ivy の解決ロジックを掘り下げて不要なものを除外するよりも、フィルタリング メカニズムとして 2 つの個別のリポジトリを使用する方がはるかに簡単です。

于 2012-09-19T18:04:05.643 に答える
2

maven-version-plugin、具体的にはスナップショットのロック/ロック解除の目標を見てください。これらは、アセンブリが使用している依存関係を特定するのに役立ち、十分な場合があります。

そうでない場合は、はい - maven はstaging repositoriesを使用できますが、ステージングしたいものがローカルの開発者リポジトリでもプルされると、混乱を招く可能性があります。

同様の問題を解決するために現在使用しているのは、maven-release-plugin と多少同等の「スクリプト化された」ものであり (実際には何らかの操作でそれを呼び出します)、厄介なバージョン管理スキームです: 私たちの開発ブランチは 1.2-SNAPSHOT のままですが、リリース済み/公開済みのビルドは、異なるバージョン管理スキーム (1.2.3、1.2.4) を使用しています。私たちのスクリプトも git タグを付けます。

于 2012-09-19T17:46:37.767 に答える
1

Maven リリース プラグインは使用せず、スナップショットも使用しないことをお勧めします。迅速かつクリーンな方法でリリースするには、こちらをご覧ください。

于 2012-09-24T21:09:42.690 に答える