MSBuild で ASP.NET のデプロイ用ファイル セットを作る

クロスワープの大鷲です。
今回は Web アプリのビルドについてです。

MODD は ASP.NET 製のシステムです。
ASP.NET アプリケーションのデプロイは、皆様いろいろな方法をお持ちのことと思いますが、当社では基本的に、ファイルを Web サーバーにコピーして IIS の仮想パスを変更するというのを、自前のスクリプトで行っています。
Visual Studio で Web アプリケーション プロジェクトを「発行」すると、Web サーバー上に配置できるデプロイ用ファイル セットを作ることができますが、この際に発行方法として「ファイル システム」を選択すると、サーバー上にそのままコピーできるファイル一式を作ることができます。*1
f:id:cw_owashi:20160909160036p:plain

この「発行」操作を自動化して Jenkins なり何なりに仕込むことが出来れば、自動ビルドができるわけですが、どうすれば実現できるのか、しばらく試行錯誤していました。

結論から言いますと、こうです。

msbuild.exe solution.sln /t:Build /p:DeployOnBuild=true /p:DeployTarget=WebPublish /p:PublishProfile=FS

あらかじめ VS で一度「発行」をして、Properties ディレクトリ(VB の場合は My Project ディレクトリ)内に発行プロファイル(*.pubxml ファイル)を作っておく必要があります。
上記のコマンドの /p:PublishProfile オプションにはそのプロファイルの名前を指定します。
あとはコマンドを叩けば、「発行」で指定した場所*2にファイル一式が出来上がります。
web.config の変換も仕込んでおけば完璧です。

ちなみにこの方法は、私が試した限り、ASP.NET MVC でも ASP.NET Core でも WebForms でも利用可能でした。

ソリューション ファイルに対して適用できるところもポイントです。
ソリューション ファイルをビルド対象とすることのメリットは

  • プロジェクトが増えても自動ビルドの定義を変えなくてよい
  • Web アプリケーション以外も普通にビルドされる

という 2 点です。
後者は、コンソール アプリケーションやテスト プロジェクトが混ざっていても大丈夫ということです。

以前の試行錯誤の中で、ターゲット(msbuild の /t オプション)に "WebPublish" 等を指定するといった方法も見つけたのですが、それでは Web アプリケーション以外がエラーになってしまうのが悩みの種でした。*3
かといって、Web アプリケーションだけビルドするのでは、自動テストができません*4
ソリューションを丸ごとビルドし、かつ、Web アプリケーションだけは自動的にデプロイ用ファイル セットを作れるということで、今のところこれが理想の方法だと思っています。

注意点は、すべての Web アプリケーション プロジェクトに同名の発行プロファイルを作っておく必要がある点と、発行先を相対パスで指定する場合はソリューション ディレクトリではなくプロジェクト ディレクトリが基準になる点くらいでしょうか。

よりお勧めの方法をご存じでしたら是非コメントをお寄せください。

*1:一旦「カスタム」を選ばないと作ることができませんが、個人的に「ファイル システム」が最もプレーンで取り回しがしやすい方法だと思っています。

*2:pubxml に書かれています。プロジェクト ディレクトリからの相対指定も可能です。

*3:csproj に対して XML 変換をかけて Web アプリケーションだけ DefaultTargets を変えるという方法を試したこともありました

*4:テストツールにもよると思いますが。dotnet test だと自動でビルドしてくれるのでいいですね。