kkamegawa's weblog

Visual Studio,TFS,ALM,VSTS,DevOps関係のことについていろいろと書いていきます。Google Analyticsで解析を行っています

Visual Studio Team Services CI/CDアドベントカレンダー:NuGetパッケージのCIとパッケージ機能(18日目)

はじめに

これはVisual Studio Team Services アドベントカレンダー18日目の記事です。

qiita.com

VSTSにはNuGet/maven/npmパッケージソース機能が用意されています。大部分の用途ではパブリックな公式サイトから取ってくればいいのですが、特定のバージョンのまま検証が済むまでアップデートをさせたくない、というケースはあり得ます。

オンプレミスのTFSを使う場合、インターネットへの接続を(今時ではちょっと難しくなりましたが)抑止したい場合にもパッケージサーバー機能は有効です。

なお、パッケージ機能に関しては、BASICライセンスでは使えません。有償ライセンスを買うか、VS Enterpriseサブスクリプションを購入する必要があります。

当然継続的インテグレーションも可能になっています。使い方を紹介します。

パッケージフィードを作る

まずはパッケージフィードを作らなくては話になりません。Packagesから作成します。ここではすでに作っているので、New feedをクリックします。

f:id:kkamegawa:20171218205721p:plain

わかりやすいフィード名を追加します。

f:id:kkamegawa:20171218205720p:plain

プライベートか、VSTSアカウントが使える人なら誰でも使えるようにするのかという設定、Upstream(nuget.orgやnpm.org,mavenなど)をソースにするのか、ここに登録したパッケージのみ使えるようにするのか、といった設定を行います。

f:id:kkamegawa:20171218205724p:plain

フィード作成直後は当然ですが何もありません。ここから作っていきます。Connect to feedをクリックすると、この作成したフィードに接続するための情報が表示されます。

f:id:kkamegawa:20171218205726p:plain

フィードには正式版以外にもプレリリース(nugetであれば-preオプション必須のパッケージ)版のパッケージなどを設定できます。

nuget/maven/npm/gradleといったパッケージのソースとして使うこともできます。

f:id:kkamegawa:20171218205727p:plain

コマンドでVisual Studioのパッケージソースとして追加できます。表示されているコマンドをそのままコピペして、実行します。

f:id:kkamegawa:20171218205728p:plain

正常に追加されると、Visual Studioのnugetパッケージマネージャーのソースとして追加されているのがわかります。

f:id:kkamegawa:20171218205725p:plain

nugetパッケージのCI

これでどハマりしました。久しぶりで、その上以前使っていたタスクが非推奨になっていたので、一からやり直しの上に、.NET Coreにも罠が待っていました…。そのうち改善されるとは思います。

今回は.NET Coreのライブラリをnugetパッケージにするためのビルド定義を作ります。通常の.NET Coreテンプレートからで構いません。

f:id:kkamegawa:20171218205717p:plain

NuGetのバグ回避のため、最新版をスタンドアロンインストールするタスクを追加しておきます。本来は.NET Core SDKでもnupkg作れるようですが、nugetを使います。

f:id:kkamegawa:20171218205718p:plain

現在のHosted VS2017 agentに入っているnugetでは.NET Coreのnugetパッケージが作れないという既知のバグがあります。ちょっとダサいですが、hosted agentのmsbuildをフルパスで呼び出して以下のタスクを実行します。

msbuild.exe /t:pack /p:Configuration=$(BuildConfiguration)

ビルドしたnupkgファイルをartifactstagingフォルダにコピーします。

f:id:kkamegawa:20171218205716p:plain

nuget pushコマンドで作成したVSTSローカルのパッケージフィードに登録します。

f:id:kkamegawa:20171218205715p:plain

これでビルドすると、先ほど作ったパッケージフィードに登録されています。ここではやっていませんが、ビルドごとにパッケージバージョンののインクリメントを実行することもできます。

f:id:kkamegawa:20171218205719p:plain

クロスプラットフォーム対応nupkgの生成

.NET Coreの場合、macOS/Windows/Linuxと複数プラットフォームのバイナリが入ったnupkgを要求されることがあると思います。そういう場合、以下の方法で実施できるでしょう。

  • Hosted VS2017/Hosted Linux/Hosted macOSそれぞれのエージェントでマルチフェーズビルドを実施する
  • ただし、それぞれのフェーズではnupkgを作らず、生成されたdllのみをartifactとして登録する。
  • Release 定義でartifactを取得して、nupkgを生成する

それぞれのhosted agentでは当然サーバーが違うので、複数フェーズビルドでは最後にnupkgをまとめることはできませんが、artifactとして一つにまとめることはできるので、バイナリのみ集めておいて、Releaseでnupkgを作ればいいでしょう。

パブリックとプライベートの使い分け

通常、stableのリリース版はnugetやnpmに発行すればいいですが、内部のプレリリース開発用までnugetに出していると煩雑です。そういう場合のために、外部に公開する前にVSTSのnugetサーバー機能を使って評価すればいいでしょう。

個人的にはdevブランチをビルドするとVSTSのPackageへデプロイ、masterブランチをビルドするとnugetへ登録するというビルド定義を作っています。

おまけ

このビルドがやたら時間がかかってしまい(Windows のビルドエージェントがいつもより遅かった気がする)、ビルドの無償枠がだいぶ溶けました…。