
GitFlowとSemantic Versioningをどのくらいの時間使用していますか 、まだ何かが足りないと感じています。 どちらの概念も優れていますが、さまざまな分野の問題の解決策を提供するため、それらを共有することは本来より複雑に見えます。
おそらくその理由は、私が最も最適なパスを選択しなかったためであり、これは将来の投稿のための良いトピックかもしれません。 同じように、アプリケーションとライブラリのリリースを管理する簡単なアプローチを説明したいと思います。
問題
適切な統合テストを行わないと、リリースビルドが本番環境に入らないようにする方法は? NuGetパッケージが静的アナライザーによって検証されるまで公開されないようにする方法は?
これらの問題を解決できるツールのほとんどはすでに存在しており、私たちはそれらを「手動モード」で使用することがよくあります。 実際、このすべてをわずかに自動化する必要がありますが、このためには適切な規則とパターンを入力する必要があります。
ツール
現状を説明します。
環境
実稼働環境でテストする能力やインフラストラクチャがない限り、従来のアプローチは、統合テストや受け入れテストなど、リリースライフのさまざまな段階で異なる環境を使用することです 。 特定のアプリケーションビルドがその環境にしかアクセスできないことを常に確認しておくと便利です。 これを行うには、各バージョンを一意に識別する機能が必要です。
セマンティックバージョニング
バージョンの割り当て対象を詳細に検討する前に、ソフトウェアの一般的なバージョン管理方法を検討する必要があります。 このトピックは新しいものではなく、幸いなことにセマンティックバージョニングがありますが、 まだバージョンを把握する必要があります。
.NET開発者にとっての素晴らしいボーナスは、NuGetおよびほとんどのパブリックパッケージによるこのアプローチのほぼ完全なサポートです 。
Gitflow
私が携わったほとんどのプロジェクトでは、GitFlowはかなり自然な選択のようです。 変更の頻度または数のために複雑すぎることが判明した場合は、 GitHub Flowにいつでも「ロールバック」できます。ここで、各変更はいわゆる「ホットフィックス」です。
このモデルでは、Gitはまったく必要ないことに注意してください。 実際にALMレンジャーが書いていること 。 ただし、Gitを使用すると、このようなモデルはSubversionよりも簡単に機能します。
すでに十分に文書化されているブランチを操作するためのさまざまな戦略については詳しく検討しません。
何を忘れる
古き良き時代では、上記のツールのほとんどが存在しないか、広く使用されていなかったため、すべての環境で1つのバージョンを段階的に展開することが一般的でした。 これらのアプローチの1つは、バイナリファイルを特別なリポジトリにコミットし、さまざまな環境に対応するブランチをさらに進めることでした。 これにより、意味のないマージや、構成ファイルの競合さえ発生する場合がありました。 これは多くの場合、Robocopyのカスタム展開スクリプトで「調整」されました。
多数の手動操作にはエラーが発生します。 原則として、間違いを犯す可能性がある場合は、おそらく間違いを犯します。 したがって、このアプローチと、前の段落で読んだすべてのものを忘れてください。
次のアプローチ
上記の概念を適切なツールと一緒に適用する方法を見てみましょう。
アーティファクト
簡単に識別できるように、ビルドサーバーによって生成されたアーティファクト(ビルドとライブラリ)をバージョン管理します。 基本的な要件は、アーティファクトを変更のソースにリンクする機能(Gitでハッシュをコミットする)と、アーティファクトを生成したプロセス(ビルドID)です。 ほとんどのCIツールには内部アセンブリカウンターがあり、この情報を利用できます。
再利用可能なコンポーネント(ライブラリ)を操作するための.NETの世界の標準は、パッケージマネージャー(NuGet)です。 Octopus Deployなどのデプロイメントマネージャーを使用すると、配信されたすべてのアーティファクトに同じ概念を適用できます。 しかし、このメタ情報とアーティファクトを正確に収集してリンクするにはどうすればよいでしょうか?
ブランチとリリース
環境に対応するブランチを使用する代わりに、どの種類の環境にデプロイすべきかについての情報がすでに含まれている成果物を作成しましょう。 つまり、特定のアーティファクトを特定の環境に関連付けます。 各環境の用途を把握し、このメタ情報を取得することで、展開の次の段階に関する決定を自動的に行うことができます。
まず、特定のブランチから構築されたアーティファクトがどの程度「安定」しているかを判断する必要があります。
支店 | リリースタイプ | バージョン形式 |
---|---|---|
特徴 | アルファ | #メジャー#マイナー#リビジョンa#ビルド#機能 |
開発する | ベータ版 | #メジャー#マイナー#リビジョンb#ビルド |
解放する | リリース候補 | #メジャー#マイナー#リビジョンr#ビルド |
ホットフィックス | リリース候補 | #メジャー#マイナー#リビジョンr#ビルド |
マスター | 安定した | #メジャー#マイナー#リビジョン |
上記の形式を使用して、たとえば、プロジェクト内のすべてのアセンブリに(共通に)共通のファイルにアセンブリメタデータを記述することができます。
[assembly: AssemblyVersion("#major.#minor")] [assembly: AssemblyFileVersion("#major.#minor.#revision.#build")] [assembly: AssemblyInformationalVersion("#major.#minor.#revision[-prerelease]")]
AssmeblyInformationalVersion
場合、前の表で定義されている形式を使用します。
したがって、バージョンには、実行時とCIビルドの識別、および結果を含むパッケージのバージョンの両方について、セマンティックバージョニングに従って番号が付けられます。
GitFlowベースの手順を例として使用すると、適切なブランチにコミットした後にCIシステムによって生成されるNuGetパッケージのバージョンは次のようになります。
挑戦する | 支店 | CIビルド番号 | NuGetパッケージバージョン |
---|---|---|---|
機能1を実装する | 機能1 | 1 | 1.2.0-a1feature1 |
機能#2を実装する | 機能-2 | 2 | 1.2.0-a2feature2 |
機能1を実装する | 機能1 | 3 | 1.2.0-a3feature1 |
完全な機能#1 | 開発する | 4 | 1.2.0-b4 |
完全な機能#2 | 開発する | 5 | 1.2.0-b5 |
リリースを安定させる | リリース-1.2.0 | 6 | 1.2.0-r6 |
本番へのリリース | マスター | 7 | 1.2.0 |
生産の問題を修正 | ホットフィックス-1.2.1 | 8 | 1.2.1-r8 |
本番へのリリース | マスター | 9 | 1.2.1 |
このパターンは、バージョンごとにパッケージをソートする際にリリース準備が向上するという自然な順序をよく反映しています。
リリースまたはホットフィックスを作成するとき、共有メタデータファイルのバージョン番号を手動でインクリメントし、リポジトリにコミットすることを好みます。 したがって、バージョン番号はプロジェクトのローカルコピーに関連します。
配備
重要なポイントは、誤った環境への偶発的な展開に対する保護です。 最初の防衛線は、単体テストに合格しないビルドをクラッシュさせるCIサーバーです。 さらに、GitHubを使用する場合、いわゆる保護されたブランチに注意を払うことができます。
Octopus Deployには、さまざまな環境で段階的にリリースできるライフサイクルコンセプトがあります。 ただし、この記事で検討したアプローチでは、展開段階ごとに異なる成果物が得られます。 これは、各アーティファクトが許可された環境にのみデプロイされるように追跡する必要があることを意味します。
リリースタイプ | 許可された環境 |
---|---|
アルファ | D |
ベータ版 | T、D |
リリース候補 | A、T、D |
安定した | P、A、T、D |
展開マネージャーが、ネイティブレベルのビルドバージョンに応じて異なるライフサイクルの同様の構成をサポートしていない場合、原則として、単純なスクリプトの形式で自分で実装できます。 ビルドの種類に関する情報をビルドバージョンにエンコードすると、リリースの安全で自動化された作成と展開のためのシンプルで信頼できるツールが得られます。 このような自動化は、Octopus Deployで自動リリース作成を使用する場合と、スケジュールに従って実行されるいわゆるリリーストレインを使用する場合の両方で可能です。
代替案
リリースとパッケージバージョンの同じ数字は疑わしいようです。 実際、リリースとアーティファクトの概念に分離はありません。 これは、ライブラリ用のNuGetパッケージの場合に特に顕著です。この場合、個別のバージョン番号付けスキームがあれば便利です。 このようなスキームは、 VCSのタグに依存する場合があります(リリースにタグをタグ付けしますか?)。
比較的最近、私はGitVersionに出会いました。GitVersionはそのような概念をネイティブにサポートし、同時にカスタマイズの柔軟性を提供します。 明らかに、彼に注意を払うことは理にかなっています。
おわりに
この記事では、アプリケーションと個々のコンポーネント(ライブラリ)のリリースビルドを管理する簡単なアプローチを検討しました。 これらのアイデアが何らかの形で役立つことを願っています。
[翻訳者注]これは、リリース管理に対する曖昧なアプローチです。 同僚、リリースとバージョン管理がどのように調整されているか教えてください。