セマンティックバージョニング
セマンティックバージョニング は、リリース可能なソフトウェアコンポーネントで行われたAPI変更の程度に基づいてバージョン番号をインクリメントするための3層のバージョニングシステムです。 これは、依存するコンシューマおよびAPI実装のパッケージまたはモジュールのプログラムによる互換性を伝達するための標準規格です。 パッケージがプログラム的に(つまり、セマンティックに)プロジェクトと互換性がない場合、 Bnd (Liferayで生成されたモジュールプロジェクトをビルドするときに使用)は、そのプロジェクトのビルドにすぐに失敗します。
セマンティックバージョンの形式は次のようになります。
MAJOR.MINOR.MICRO
特定のイベントにより、各層が強制的にインクリメントされます。
- メジャー: 互換性のない、APIを破る変更が行われました
- マイナー: APIのプロバイダーのみに影響する変更、または新しい下位互換性のある機能が追加されました
- マイクロ: 下位互換性のあるバグ修正が行われました
セマンティックバージョニングの詳細については、公式の セマンティックバージョニング サイトおよび OSGi Allianceのセマンティックバージョニング テクニカルホワイトペーパーを参照してください。
Liferayのモジュールはすべて、セマンティックバージョニングを使用しています。
DXPは何百もの独立したOSGiモジュールを含むモジュラープラットフォームであるため、セマンティックバージョニングに従うことが特に重要です。 相互に依存する多くの独立したモジュールがあるため、互換性を宣言する方法がないと、新しいパッケージバージョンをリリースすることが恐ろしくなります。 セマンティックバージョニングのわかりやすいシステムとLiferayのツールは、モジュールの互換性を管理するのに役立ちます。
プロジェクトのベースライン設定
セマンティックバージョニングを手動で実行するのは一見簡単に思えます。 善意の開発者がプロジェクトのセマンティックバージョンを手動で更新したが、後で間違いだと気づくという悲しい歴史があります。 実際のところ、単純なアップデートの影響を予測することは困難です。 これを回避するには、プロジェクトが更新された後にプロジェクトの ベースライン を設定できます。 これにより、プロジェクトがセマンティックバージョニングルールに準拠していることを確認し、人間には必ずしも明らかではないAPIの変更をキャッチできます。 LiferayのBaseline Gradleプラグインを使用して、ベースライン機能を提供できます。 これをGradleビルド構成に追加し、次のコマンドを実行します。
./gradlew baseline
このBaseline Gradle Pluginプラグインは、 Liferay Workspace ではデフォルトで提供されていません。
baseline
コマンドを実行すると、プラグインは新しいモジュールのエクスポートされたパブリックAPIを最新のリリースされた非スナップショットモジュールと比較します。 変更がある場合は、OSGiセマンティックバージョニングルールを使用して、最小の新しいバージョンを計算します。 新しいモジュールのバージョンが低い場合、エラーがスローされます。
ツールだけに頼らないでください。 Javaクラスまたはインターフェイスのシグニチャーや、API 使用 の変更(つまり、メソッド呼び出しの順序に関する仮定、または入力および/または出力エンコーディングの変更)に表されていない互換性の変更を識別するには十分ではありません。 ベースラインとは、その名が示すように、互換性の問題が大量に発生することがないような、ある程度の 指標となる 快適さを提供するものです。
ベースラインを設定すると、プロジェクトのセマンティックバージョニングはAPIが表現するのと同じくらい正確になります。
アーティファクトと依存関係のバージョンの管理
セマンティックバージョニングを使用してプロジェクトのアーティファクトと依存関係のバージョンを追跡する方法は2つあります。
- バージョンの範囲
- 正確なバージョン(1対1)
複数のDXPバージョンのプロジェクトをビルドし、最大限の互換性を維持する場合は、さまざまなバージョンを追跡する必要があります。 つまり、アプリで複数のパッケージバージョンが動作する場合は、それらのいずれかを使用するようにアプリを構成できます。 さらに、Bndはモジュールが依存する各パッケージのセマンティックに互換性のある範囲を自動的に判断し、モジュールのマニフェストに記録します。
バージョン範囲の構文については、 OSGi Specifications を参照してください。
OSGiバンドルのbnd.bnd
にインポートされたパッケージのバージョン範囲は次のようになります。
Import-Package: com.liferay.docs.test; version="[1.0.0,2.0.0)"
一般的なビルドツールもこの構文を採用しています。 Gradleでは、依存関係のバージョン範囲は次のようになります。
compile group: "com.liferay.portal", name: "com.liferay.portal.test", version: "[1.0.0,2.0.0)"
最新のリリースバージョンを指定することも、上限のないバージョンの範囲と見なすことができます。 Gradleで指定する方法は次のとおりです。
version: "latest.release"`
さまざまなバージョンを追跡するには、それなりの対価が必要です。 問題をデバッグしているときに、古いビルドを再現するのは困難です。 また、使用するバージョンによって動作が異なるリスクもあります。 また、大きな変更が導入された場合、最新のリリースに依存すると、プロジェクトとの互換性が失われる可能性があります。 バージョンの範囲を指定する場合は慎重に行い、含まれるすべてのバージョンでプロジェクトをテストしてください。
依存関係の正確なバージョンを追跡する方が安全ですが、柔軟性は低くなります。 特定のDXPバージョンに制限されたり、その特定のバージョンにのみ存在するAPIにロックされる可能性があります。 ただし、モジュールをテストするのが非常に簡単で、予期しない障害が発生する可能性が低くなります。
bnd.bnd
ファイルでパッケージバージョンを指定する場合、正確なバージョンは通常、version="1.1.2"
のように指定されます。 ただし、この構文は技術的には範囲であり、[1.1.2, ∞)と解釈されます。 したがって、パッケージのより高いバージョンが利用可能な場合は、指定したバージョンの代わりにそのバージョンが使用されます。 このような場合、テスト済みの互換性のあるバージョンのバージョン範囲を指定する方がよい場合があります。 真の完全一致を指定したい場合は、[1.1.2]
のような構文になります。 詳細については、OSGi仕様書の Version Range セクションを参照してください。
1つのバージョンのみが指定されている場合、Gradleは正確なバージョンを使用します。
これで、依存関係を範囲で追跡する場合と完全一致で追跡する場合の長所と短所がわかりました。