NuGet

NuGet ギャラリーを作成する

**Clark Sell
**Mark Nichols

開発者向けの新しいパッケージ管理エコシステムとして NuGet を紹介してきたこのシリーズも今回 3 回目、これが最終回です。NuGet は、.NET 開発者がパッケージを使用、作成、および公開できるようにする Outercurve Foundation のプロジェクトです。本シリーズではこれまで、NuGet でプロジェクト ライブラリを管理する方法 (msdn.microsoft.com/magazine/hh547106) と NuGet でパッケージを作成する方法 (msdn.microsoft.com/magazine/hh708753) を紹介してきました。今回は、NuGet ギャラリーを独自にホストし、ビルド プロセスを構築してパッケージ管理に役立てる方法を説明します。

ギャラリーをホストする理由

NuGet パッケージのパブリック レジストリとして NuGet.org (英語) が既に存在するのに、なぜギャラリーをホストするのでしょう。これはもっともな疑問です。では、自身を取り巻く独自の開発環境の中でこのパブリックなエコシステム インフラストラクチャを活用すると考えたらどうでしょう。プライベートなギャラリーを独自にセットアップして、製品の開発エコシステムを支援するだけでなく、ビルドと開発のプロセスをこのエコシステムに直接関連付けたら、もっとすばらしいと思いませんか。そのうえ、NuGet.org (英語) で公開されているすべてのものは無償で利用できます。

今回は、独自の NuGet ギャラリーを作成および使用するのに必要な手順について説明します。以前のシリーズでも述べたように、NuGet を開発ライフサイクルに組み込むのは難しいことではなく、十分取り組む価値があります。NuGet を開発ライフサイクルに組み込んだら、パッケージの使用、作成、および配布にかかわる問題に頭を悩ませていたのが、遠い昔の思い出になります。

その前に、多くの開発者が直面してきたユース ケースとして、バージョン管理について考えてみましょう。製品の全体サイズや複雑さによっては、多くのチームに分かれて製品を作成することがよくあります。このような場合、チームごとにリリース スケジュールが異なり、作成するアセンブリも異なります。もちろんリリースする製品は顧客向けにうまくまとめられますが、完成までには数千とは言わないにしても数百ものビルドが繰り返され、さまざまなバージョンの製品資産が量産されます。

ここ 10 年、こうした手間の軽減に役立つ開発手法 (自動ビルド システムや自動配置システムなど) が生まれましたが、配布と選択の方法に関してはどれも不十分でした。パッケージ管理システムは、こうした問題に解決策を提供します。

さまざまなチームが個別に作業を行い、チームが独自に選択したバージョンを発行している開発エコシステムについて考えてみてください。それぞれのチームにビルドとリリースの独自のスケジュールがあり、各チームが自身の製品を簡単な方法で管理しようとします。パッケージ管理システムを使えば、各チームは作成する製品とインストール方法を決定でき、顧客はどの時点の製品を使用すればよいかを判断できます。

これはある意味で、オープン ソース コミュニティが、実績があり簡単に応用できる手法を利用して機能しているのに非常によく似ています。NuGet.org (英語) で見つかるパッケージはかなり「目の粗い」ものですが、独自のアプリケーションを構築する際もこれと同じ手法を利用できます。この方法が役に立つソフトウェアの具体的な好例として、企業がパブリックな製品用に構築および管理するヘルパー ライブラリが挙げられます。

おそらく、企業が利用する場合、開発者が使用してもかまわないライブラリとバージョンを限定することになります。これが独自のギャラリーをホストするもう 1 つの大きな理由です。独自にホストするギャラリーでは、承認済みのパッケージとパッケージ バージョンのみを含みます。

迅速かつシンプル

独自の NuGet ギャラリーをホストする最も簡単な方法は、ファイル共有を公開する方法です。少し初歩的に聞こえるかもしれませんが、迅速でシンプルなギャラリーが必要なら、この方法が非常に有効です。ファイル共有は自身に適した方法で構造を設定し、その共有の好きな場所にパッケージ (*.nupkg ファイル) を配置します。このファイル共有をパッケージ ソースとして参照できます。

作成したパッケージ ソースを開発環境に追加します。パッケージ ソースは必要な数だけ追加でき、複数のパッケージ ソース間を簡単に移動できます。Visual Studio でパッケージ ソースを編集するには、[ツール]、[オプション]、[Package Manager] (パッケージ マネージャー)、[Package Sources] (パッケージ ソース) の順にクリックします (図 1 参照)。この記事の執筆時点では、1.5 が最新版です。NuGet のバージョンによって、やや違いがある場合があるので注意してください。

Adding a Package Source in Visual Studio図 1 Visual Studio におけるパッケージ ソースの追加

ここで、既定のパッケージ ソースを追加、削除、および変更できます。お望みなら、無償の開発環境の WebMatrix でも同じことが可能です。メイン メニューの [NuGet Gallery] (NuGet ギャラリー) アイコンをクリックして、[Add Source] (ソースの追加) をクリックするだけです (図 2 参照)。

Adding a Package Source in WebMatrix図 2 WebMatrix におけるパッケージ ソースの追加

ご覧のとおり、どちらの図でも 2 つのパッケージ ソースが一覧されています。その 1 つまたは両方をいつでも選択して使用できます。

NuGet ギャラリーの導入

ファイル システム パッケージ ソースはセットアップから使用開始まで実に簡単ですが、スケール アウトを始めると途端に正常に機能しなくなります。さいわい、NuGet.org (英語) ではまさにこの事態が考慮されており、ユーザーが必要に応じて入手、拡張、および構築に利用できるオープン プラットフォームが用意されています。NuGet ギャラリー プロジェクトは、github.com/NuGet/NuGetGallery (英語) にあります。NuGet ギャラリーは、Razor、OData、SQL Server、および Windows Azure に基づいて構築された ASP.NET MVC 3 プロジェクトです。

開発エコシステムを提供する NuGet ギャラリーの特徴と機能を理解するには、単に NuGet.org (英語) を閲覧するのが最善の方法です。

パッケージを作成して公開するには、まずユーザー登録が必要です。登録すると、パッケージのアップロードと管理、プロファイルの編集などを行う完全な権利が与えられます。固有の API キーを生成してギャラリーへのパッケージの公開を自動化することもできます (図 3 参照)。パッケージ公開の詳細については、このシリーズ前回の「パッケージを作成して NuGet で公開する」を参照してください。

A Registered User Account in NuGet図 3 NuGet の登録ユーザー アカウント

NuGet ギャラリーにパッケージをアップロードする際、ギャラリー内の固有の場所が自動的に与えられます (図 4 参照)。

A Package Uploaded to the NuGet Gallery図 4 NuGet ギャラリーにアップロードされたパッケージ

そこでパッケージに関する重要な情報をすべて確認できます。それぞれのパッケージについて、NuGet ギャラリーは特定のバージョンのダウンロード数、ダウンロードの総数、日付、ライセンスなどの情報を追跡します。もちろん、NuGet.org (英語) サイトのパッケージは、エコシステムから考えられるよりもかなり多いダウンロード数を算出する可能性が高いのですが、これらの統計はプロジェクトの規模を問わずすべてのパッケージ作成者にとって不可欠です。

パッケージのフィードは、明らかにスタック全体で最も重要な機能です。これは、http://YourGallery/api/v2 (英語) にある OData フィードです。パッケージ ソースに使用するのと同じ URL です。このフィードがないと、NuGet のすべての能力が失われます。

作業の開始

開始する前に、以下をインストール済みであることを確認します。

この記事の執筆時点では、NuGet ギャラリー用のインストーラーはなく、このプロジェクトは今まさに精力的に開発中です。つまり、最新の情報を得るには、プロジェクトのホームページを見るのが一番です。ソースをダウンロードしてビルドする必要がありますが、これは簡単です。

ソースを取得するには、最新のマスター ブランチの zip 形式のコピーを単にダウンロードするか、次のように git でソース ベースの複製を作成できます。

$ git clone https://github.com/NuGet/NuGetGallery.git

これを実行すると、完全なソース ベースをローカルに保有できます。ルートに、Build-Solution.ps1 という Windows PowerShell スクリプトがあります。このスクリプトを実行し、コンピューターをセットアップしてソースをビルドします。

ソースを実行すると、見た目も雰囲気も NuGet.org (英語) とそっくりなのがわかります。UI を微調整したり、ホームページを修正することを考えるかもしれません。それもよくわかりますが、特にマスター ソース ベースと同期を維持する必要がある場合は注意が必要です。

ビルド プロセスと NuGet ギャラリーの統合

次に必要な手順は、NuGet ギャラリーを既存のビルド プロセスに統合することです。ビルド プロセスがなく、Team Foundation Server (TFS) のビルド プロセスのちょっとした入門ガイダンスを探している場合は、rabcg.codeplex.com (英語) から Microsoft Visual Studio ALM Rangers のビルド カスタマイズ ガイドを参照してください。

さて、ギャラリーから利用可能にするライブラリが用意できました。このギャラリーは、公式の NuGet ギャラリー、独自のギャラリー、または単なるローカルのファイル共有でもかまいません。いずれの場合でも、所定の作業を実行して NuGet パッケージを作成する必要があり、ギャラリーの形態を問わず実行する作業は通常同じです。

製品開発の過程では、コードの作成、コンパイル、パッケージ化、プッシュ、および公開のプロセスを繰り返します。また、十分なテストを含めることもお勧めします。このようなテストの結果から何か問題が見つかった場合は、ギャラリーへの公開を避けます (図 5 参照)。

The NuGet Development Process図 5 NuGet の開発プロセス

利用者がソフトウェアの動作に満足し続けることは重要で、管理されたプロセスを使用すれば比較的容易にこれを行えます。ただ、管理されたプロセスは完全に自動化することはできず、人間が行う検証に代わるものはないことを覚えておいてください。公開できるからといって、ソフトウェアがすべての自動テストに合格しているわけではありません。未完成のパッケージでも簡単に公開でき、利用者の怒りをかうこともあります。さらに、ひっきりなしに公開しても、利用者は変わり続ける新しいバージョンについていけず、困惑することになります。よく考えて公開するようにしてください。

ビルド プロセスを使って NuGet ライブラリをビルドしてパッケージ化したうえでギャラリーにプッシュし、最終テストと目視による検証を行います。こうして、継続的統合または定期ビルドを選択し、パッケージを自動的にプッシュしてテスト可能な状態にできます。これはどのように行えばよいでしょう。ここでは、TFS とそのワークフローに基づく自動ビルド機能を使用する例を紹介します。

NuGet.exe はスタンドアロンのパラメーター駆動型コンソール アプリケーションですが、TFS チーム ビルドなどの他のプロセスから簡単に呼び出せます。チーム ビルドはワークフローを実行します。TFS の用語では、これはビルド テンプレートを通して管理され、ビルド定義によって開始される一連のカスタム アクティビティです。NuGet の開発プロセスを自動化するパッケージ ソリューションに、nugetter.codeplex.com (英語) から利用できる NuGetter プロジェクトがあります。このプロジェクトは、NuGet.exe アプリケーションに関する自動化されたシェルを提供します。実行できることと、NuGet パッケージの自動化に取り組む際の考慮事項を説明するために、このパッケージを使用します。

図 6 に示すように、TFS におけるビルド定義では、パッケージ化、プッシュ、および公開を実行するのに必要なすべての情報を提供します。NuGet 用の柔軟で反復可能なビルド プロセスの構築には、いくつかのデータと、プロセスの一部を有効と無効に切り替えるスイッチが必要です。データは、実行する手順の順序がわかるような名前の付いたカテゴリに整理します。

Nugetter Build Template図 6 Nugetter ビルド テンプレート

PrePackaging セクションは、いくつかの初期準備が必要な、複雑な NuGet や複数フレームワークの NuGet のパッケージ化に使用します。NuGetter は、(必要に応じて) Windows PowerShell スクリプトを呼び出し、ライブラリ ファイルを整理してパッケージ化を簡略化します。この手順は必須ではないので、フラグ パラメーター "Invoke PowerShell Script" (PowerShell スクリプトを呼び出す) を使用して、スクリプトを実行するかどうかをプロセスに指示します。

.nuspec ファイルを使用してパッケージを作成する方法を直接定義することも、.csproj ファイルを使って間接的に行うこともできます。必要に応じて、適切な方法を選択してください。

ご覧のように、パッケージ化に必要なすべてのパラメーターを含めます。バージョン、ベース パス (パッケージ化用のソース フォルダ)、API キー、およびギャラリーの場所 (Source という名前) を、すべてビルド定義の一部として提供します。ただ、非常に重要なのはこの情報のセキュリティの問題です。たとえば、API キーは作成者だけが NuGet パッケージをギャラリーにプッシュできるようにするものです。このキーが公開されたら、だれでも作成者の名を使って偽のパッケージをプッシュできることになります。このため、NuGetter では実際の API キーかキーを格納しているファイルのパスのどちらを提供するかを選択できます。ファイル パスを使用すれば、ビルド プロセスでファイルを読み取り、キーを抽出し、ログにキー情報を残すことなく使用するので、セキュリティが確保されます。もちろんこれが機能するには、ビルド サービス ID にファイルの読み取りアクセス許可が必要です。

もう 1 つ生じる可能性のある問題がパッケージのバージョン管理です。図 6 では、バージョン番号をビルド定義で指定しています。ただ、本当にビルド定義で番号を変更し続ける必要があるのでしょうか。複数のビルド (継続的統合 (CI)、日次ビルド、その他の定期ビルド、およびさまざまな手動ビルド) が行われる場合はどうなるでしょう。NuGetter では、バージョンを直接入力するか、API キーと同様、複数のビルド定義が使用できるファイル パスを提供するかを選択できます。すべてのビルド定義で同じバージョン番号を使用するため、1 か所で管理できます。

この例ではプッシュ先は NuGet ギャラリーですが、内部ギャラリーやローカルのファイル ストアにパッケージをプッシュする場合でも、ここにビルドのプッシュ先の情報を指定します。これも、ビルド プロセスで処理する必要がある部分です。NuGet.exe はプッシュ先として URL を想定するため、ローカル ストア (URL ではない) にプッシュする場合、プロセスはプッシュ先の形式を解釈する必要があります。この場合は、NuGet.exe を使用してプッシュする代わりに、ビルド プロセスでプッシュするようにします。

完全性と NuGet.exe との機能の同等性のため、NuGetter は自動公開機能を提供します。この機能の使用を決める前に、前述の注意事項を思い出してください。

ところで、利用者がパッケージの更新を見落とす心配は不要です。NuGet のコミュニティは、NuGetFeed (github.com/NuGetFeed/NuGetFeed、英語) を使用してこれに対処します。NuGetFeed では、選択したパッケージに基づくカスタムの RSS フィードをビルドできます。利用者は、お気に入りの RSS リーダーにカスタム フィードを追加し、更新の通知を受け取ることができます。

NuGet フィードを作成するもう 1 つの方法は、MyGet.org (英語) から利用できる MyGet です。MyGet は、承認済みパッケージの一覧用にプライベート NuGet フィードが必要ですが、独自のギャラリー インフラストラクチャを作成して管理するのに時間、経費、および労力を費やしたくない方に最適です。MyGet は、ニーズに合ったギャラリーを非常に迅速に作成できるホスト型のソリューションです。詳細については、MyGet サイトを参照してください。

最後に、NuGet と NuGet ギャラリーはオープン ソース プロジェクトです。つまり、だれもがドキュメントから機能に至るまで、あらゆる方法で貢献したり、その中でバグを解決したりできます。貢献するための具体的手順については、github ホームページでプロジェクト チームが詳細に説明しています。

まとめ

NuGet により、パブリックとプライベートの両方で、.NET パッケージ管理エコシステムについての考え方が変化したことは間違いありません。NuGet ギャラリーと NuGetFeed は、どちらもこのエコシステムを完成させるのに必須の構成要素です。これらのツールを日常の作業に取り入れることで、新たな可能性が開けます。繰り返しになりますが、NuGet ギャラリーは現在精力的に開発されているところなので、github.com/NuGet/NuGetGallery (英語) から最新の情報を確認してください。

今回使用したリンクはすべて、on.csell.net/HostingNuGet (英語) にまとめています。

Clark Sell は、シカゴ郊外のマイクロソフトでシニア Web エバンジェリストとして活躍しています。彼のポッドキャストは DeveloperSmackdown.com (英語) で、ブログは csell.net (英語) で公開されており、ツイッターは twitter.com/csell5 (英語) からアクセスできます。

Mark Nichols は、シカゴ郊外のマイクロソフトでシニア ソフトウェア コンサルタントを努めています。彼のポッドキャストは DeveloperSmackdown.com (英語) で、ブログは marnick.net (英語) で公開されており、ツイッターは twitter.com/mark_nic (英語) からアクセスできます。

この記事のレビューに協力してくれた技術スタッフの David EbboPhil Haack、および Brandon Satrom に心より感謝いたします。