はじめに
昨日dotnetConf関西で行ったセッション資料ではCI/CDの細かいやり方はのせていませんでしたので、ブログで詳細の解説を行います。
CIそのものはメニューのBuild & Releaseから構築します。この記事では新しいUIで説明していますが、以前のUIでもあまり関係ありません。
長くなったので、Linux版は別にします。
VSTSとビルドエージェント
VSTSには内蔵のビルドエージェント(Hosted Agent)があります。Hostedは今のところWindowsのエージェントのみになっているので、LinuxやMac環境でビルドする場合、独自のビルドサーバーを用意する必要があります。
ビルドエージェントは一台までであれば無料で接続できます。httpsのoutboundだけ通信できていればいいので、Firewallがある環境でも大体大丈夫です。
有料($15/月)支払って、一つのプールに二台以上のビルドエージェントを運用すると、並列でビルドができるようになります。並列可能ということ以外にも、エージェントを占有するので、占有しているエージェントではリポジトリのクローンが頻発しなくなるはずです。
原則1台1エージェントですが、登録するときにエージェントの名前を変えれば、一台のサーバーに複数のエージェントが登録できます。例えば、TFSとVSTSそれぞれ登録するとかもできます。サーバーの性能次第ですが、複数のVSTS/TFSを使っているときは試してみてください。
エージェントの対応OS
- .NET CoreがサポートするWindows
- Ubuntu 14.04/16.04(サービスとして動かす場合は16.04必須)
- Red Hat Enterprise Linux 7.x
- OS X 10.10/10.11
TFS 2015に接続する場合、WindowsではTFSに付属しているエージェントを使ってください。TFS "15"ではPAT(Personal Access Token)をサポートするので、.NET Core版のエージェントが使用可能になります。
VSTSのエージェントはソースも公開されています。
Windows(Hosted)で.NET Coreアプリをビルドする
では、実際にビルド定義を作ってみましょう。ASP.NET Core MVCアプリケーションを作ってコミットしておきます。
Visual Studioのテンプレートを使ってもいいですが、大部分を削除することになります。
NuGetの復元タスクを追加
Add build stepからUtilityにあるCommand Lineを追加します。
NuGetパッケージを復元する
Tool: "c:\Program Files\dotnet\dotnet.exe"
Arguments : restore
Working Folder : Project.jsonのあるフォルダ
ビルドタスク
ビルド用のCommand LineをAdd build stepで追加します。
Tool: "c:\Program Files\dotnet\dotnet.exe"
Arguments : build -c $(BuildConfiguration)
Working Folder : Project.jsonのあるフォルダ
※:BuildConfigrationはVariablesでreleaseと作っておいてください(Visual Studioのテンプレートから作った場合は作られています)
テストプロジェクトのNuGetパッケージを復元する
テストプロジェクトのNuGetパッケージ復元のCommand LineをAdd build stepで追加します。
Tool: "c:\Program Files\dotnet\dotnet.exe"
Arguments : restore
Working Folder : テストプロジェクトのProject.jsonがあるフォルダ
テストの実行
テスト実行用のCommand LineをAdd build stepで追加します。
Tool: "c:\Program Files\dotnet\dotnet.exe"
Arguments : test -xml TestResult.xml
Working Folder : テストプロジェクトのProject.jsonがあるフォルダ
Visual Studioでビルドする場合と異なり、プロジェクト単位でdotnet restoreを実行する必要があるので気を付けてください。
-xml にはテスト結果を出力するxmlファイルを指定します。テストプロジェクトごとに異なる名前にしてください。後で集計することができなくなります。
dotnetコマンドはフルパスで指定しなくても実行できますが、ビルド時に警告が出るので、フルパスを指定するほうが無難です。
テスト結果をVSTSにアップロード
Add build stepで"Publish Tests Results"タスクを追加して、ビルド結果をVSTSにアップロードします。VSTEST以外にもXUnit,NUnit,JUnit(Javaなので.NET Coreには関係ないですが)などに対応しています。
テスト結果をVSTSにアップロードすると、このようにテスト結果の品質を追跡することができます。
LnuxもしくはOS/Xでビルドする場合、出力するXMLファイル名の大文字小文字に気を付けてください。
コードカバレッジも取れるはず…Visual Studioでは取れていますが、VSTSでは集計されていません。これは少し調査します。
パッケージの出力
パッケージ出力用のCommand LineをAdd build stepで追加します。
出力パッケージを作ります。具体的にはproject.jsonで定義されているpublishの動作が実行されます。
Tool: "c:\Program Files\dotnet\dotnet.exe"
Arguments : publish src/{プロジェクト名} --configuration $(BuildConfiguration) --output $(PublishOutput) --framework $(NETCoreVersion)
注意点として、publishコマンドはデフォルトでデバッグ版を出力しています。--configurationで明示的にrelease版(ここではvariablesで指定しています)を指定してください。Azureではデバッグ版実行できない(エラーになる)はずなのですが、なぜかデバッグ版をデプロイしてもApp Serviceで動いてしまってます。長い間気づきませんでした。
Framework Runtimeは組み込むか、システムインストールを使用するかはご自由に。今回はシステム組み込みのランタイムを使用する前提でやっています。
bin\$(BuildConfiguration)\ にあるアプリケーションの実体をコピーするタスクです。このタスクは非.NET CoreのASP.NET前提のタスクのようで、フォルダ構成をそのままコピーしてくれません。
IIS(Azure App Service)にデプロイする場合、これで問題ないのですが、Linuxにデプロイするとこのタスクでは実行時に「\bin\$(BuildConfiguration)\netcoreapp1.0\モジュール名」が存在しないというエラーになります。
特別にタスクを作るか、project.jsonのpublishOptionsにbin/releaseを含めるしかないように思います。今回はproject.jsonに入れています。あと、各種jsonファイルも入っていない場合、Linux(たぶんOS/Xも)実行失敗するので、jsonファイルを忘れないようにpublishOptionsに入れましょう。
"publishOptions": { "include": [ "wwwroot", "Views", "Areas/**/Views", "appsettings.json", "project.json", "bin/release", "web.config" ] }
リリース作業用PowerShellスクリプト追加
ここはApp ServiceにリリースするためのPowerShellスクリプトをリリース成果物としてコピーするタスクですビルド時にデプロイするなら不要です。
WebDeploy用zipファイル作成
IIS(Azure App Service)にwebdeployでデプロイする場合、zipパッケージを作っておく必要があります。webdeployを使わない場合は不要です。
VSTSにリリース成果物を登録
最後に成果物をVSTSにコピーします。特定のファイル共有にコピーするか、VSTSに保存します。ファイル共有はUNCでVSTSもしくはビルドエージェントからアクセスできる必要があります。
UNCで共有フォルダにコピーする場合、独自のビルドエージェントからになるでしょうね。