azukipochette's weblog

memory dump (mini)

Team Foundation バージョン管理から Git に移行するための旅路 (1.5)

免責事項

この文書は技術文書ではない。私の思い出話や蘊蓄を多分に含んだ内容であり、とても冗長である。 また、正確性にも欠ける点があるかもしれないし、この資料を作るために時間を掛けて検証したりなどはしていない。 読者は、そういう文章であるという点を十分理解した上で、読んでほしい。

本ドキュメントは読者の参考になればと思って書いてはいるが、本文書の内容によって生じた一切について責任を負わない。 すべて "At your own risk" である。

はじめに

前回の最後に「次回は、Team Foundation バージョン管理がどうやってファイルを管理しているのかを話す」言って、今回は前回入れ忘れていた話をする。 なので、番号を 1.5 とした。次回の話に興味がある人は 2 を待って欲しい。

何を忘れていたかといえば、「ライブラリ管理」の話である。今回は、アプリが使用するライブラリをどうやって管理するのかについて話す。

今のソフトウェア開発

今どきのアプリケーション開発では、どの開発言語を使っていてもライブラリを管理するための仕組みが搭載されている。 たとえば、C++ .NET といったマイクロソフトの技術を使っている場合、Visual Studio 2012 以降では NuGet と呼ばれるパッケージ管理機能が IDE に搭載されている。 振り返ってみれば、今アプリケーションを新規で開発するのに、外部ライブラリを一切使わずに大規模なアプリを作る、というのは簡単ではないだろう。

もし、対象のプロジェクトが Visual Studio 2010 などパッケージ管理機能に対応していないような開発環境である場合、残念ながらビルドに使用するファイルはバージョン管理の中に直接入れ込むか、ビルド時に参照可能なファイル サーバーなどに配置するしかない。 一方、もし Visual Studio 2012 以降の開発環境で NuGet が使用できるならば、ライブラリを NuGet パッケージ化することを検討すると良い。

NuGet パッケージをどこで管理するか

Team Foundation Server や Azure DevOps Server を使っているならば、パッケージ管理 (Azure Artifacts) で管理できる。 以前は別途有償の機能だったが、クラウド版である Azure DevOps Services に対して Azure Artifacts の無料枠が追加されたタイミングで、無料で使えるようになった(確か 2019 年)。

もし、何らかの事情で Team Foundation Server / Azure DevOps Server 以外で管理したいという場合には、ファイル サーバー上でホストする機能もある。(たとえば、近い時期に GitHub への移行を考えていて、これ以上 Azure DevOps Serverの機能を使うことは避けたい、というケースがこれに該当するかもしれない)

自社ライブラリを NuGet パッケージ化する

これはネットで調べてもらえば、沢山事例もドキュメントも出てくるのでここでは解説しない。 強いて言うなら、次の点を意識すると良いと思う。

  • 依存ライブラリを1つのパッケージに集約しない (やりがち)
  • ライブラリの依存関係はパッケージの依存関係として管理する
  • セマンティック バージョニングを学習する

これも簡単だがそれぞれについてコメントしておく。

依存ライブラリを1つのパッケージに集約しない

アプリをビルドするために必要な依存ライブラリが 10 ファイルあったとしよう。1つずつ NuGet パッケージ化するのは面倒だな...と思っても、1つに集約することはお勧めしない。

たとえば、そのうちの1つのライブラリに脆弱性が見つかった場合、そのライブラリのために集約したパッケージを更新しなければならない。すると、パッケージのバージョン番号は、ライブラリのバージョン番号と違う値になるだろう。すると、次はパッケージのバージョンと内包されているライブラリのバージョン番号一覧を管理しなければならなくなる。そんなことはやめた方が良い。

基本的にはライブラリ単位で1パッケージにする考えで良いが、依存性が高く、ファイルとして重複しないライブラリならまとめてしまってもいいだろう。

ライブラリの依存関係はパッケージの依存関係として管理する

ライブラリが他のライブラリに依存しているということはよくある。 そのような場合は、NuGet パッケージの依存関係として nuspec ファイルに記述するとよい。

こうしておくことで、利用者が個別にパッケージをインストールする手間が減り、更新の際も楽になる。

セマンティック バージョニングを学習する

NuGet パッケージも含め、多くのパッケージ管理システムで扱われるパッケージのバージョンは「セマンティック バージョニング」と呼ばれるバージョン番号で管理されている。これは従来のバージョン番号の付け方とは異なるもので、利用者目線での影響度をバージョン番号として管理するものになっている。

自社ライブラリを NuGet パッケージとして管理する場合は、まずはこのセマンティック バージョニングで管理できないかどうかを検討してみると良いだろう。

外部ライブラリを NuGet パッケージ化する

外部ライブラリの場合は基本的に NuGet.org などのパブリック パッケージ フィードに公開されていないかどうかを確認するとよい。 有償のサードパーティ ライブラリの場合は、ライセンスの関係から NuGet.org ではなく、独自のフィード上で管理されているケースもある。面倒だが、これについてはライブラリ個別に確認するほかない。

もし、NuGet.org などのフィードからは入手できないライブラリがある場合は、自身で NuGet パッケージ化するとよい。 このときは、バージョン管理が楽になるようにファイル バージョンとライブラリ バージョンを一致させると良いだろう。

おわりに

パッケージ化できたら、プロジェクト ファイルの修正、自動ビルドの修正などを行う必要があるが、これは言及しなくても分かることだろう。 ポイントは、ライブラリ類はバージョン管理に直接入れるのでは無く、パッケージ管理側でやるべきだ、ということだ。

これは単にバージョン管理からバイナリを排除するだけでなく、DLL 地獄問題や更新時のバージョン管理の複雑さを排除するのにも多いに役立つ。 手間はあれど将来的に役立つ作業なので、ぜひやってほしい。

さて、次回こそ Team Foundation バージョン管理がどうやってファイルを管理しているのかを話そうと思う。 それでは、また次回。