銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

2017年 .NET Core 1.x (Visual Studio 2017) プロジェクト向け AppVeyor での自動ビルドの設定

ChatWork 向けのC# クライアントを開発していて、ここ1~2年は更新していなかったものの、最近.NET Core対応させたり、API endpoint v2に対応したりしてまた更新するようになりました。

github.com

2年前にAppVeyorで自動ビルド環境を作っていましたが、当時は.NET Core対応などなくVisual StudioのMSBuildでビルドしていました。今回、.NET Core対応したので、dotnetコマンド中心に自動ビルドを対応したので、そのまとめです。作ったプロジェクトはここにあります。

AppVeyor

2年前に作ったプロジェクト、publicリポジトリ向けの無償プランなのにまだビルドログまで保存されていて驚きだったんですがコミット連携とかがおかしくなっていたのでいったんAppVeyorのプロジェクトを作成しなおしました。その上で今回実現できた自動ビルドの中身はこんな感じです。

  • 任意のブランチ*1へのコミット、もしくはPRが作成されたらビルドがトリガーされる
  • 最新の.NET Core SDKでビルドする
  • AppVeyor側で採番されるビルド番号をsuffixにつけたバージョンのNuGetパッケージを生成する。逆に言うと、<Major>.<Minor>.<Patch>形式のバージョンは明示的にcsprojで指定し、AppVeyor側からは操作しない。
  • 自動ビルドで生成したNuGetパッケージはAppVeyorが持っているプロジェクトごとのNuGetリポジトリにpushする
  • (この項目だけ未テスト)GitHubにタグをpushすると、デプロイ処理が実行され、nuget.orgにリリースビルドされたパッケージをpushする。リリースビルド用のパッケージはsuffixをバージョンにつけない。

順番に見ていきましょう。

ビルド番号とトリガー

AppVeyorの場合、設定したGitHubリポジトリに対してデフォルトですべてのコミットでビルドがトリガーされます。トリガーされたくないブランチや、特定のブランチのみトリガーしたい場合はsettingsGeneralタブで指定します。また、ビルド番号形式も指定できます。{build}で自動インクリメントされる数値、{branch}でコミットされたブランチ名が入ります。

f:id:tanaka733:20170531164534p:plain

このページのほかの設定はデフォルトのままにしています。

ビルド環境の設定

最新の.NET Core SDKはVisual Studio 2017という種類のイメージを指定するとすでにインストールされています。インストールスクリプトを記述することもできるので、指定したバージョンのSDKであったりその他のツールをインストールすることもできるでしょう。gitリポジトリをcloneするフォルダは、あとあとのスクリプトの記述を楽にするために明示的に指定しています。

f:id:tanaka733:20170531164857p:plain

ビルドスクリプトとsuffixの指定

次にBuildタブでビルドスクリプトを記述します。.NET Coreプロジェクトなので、組み込みで用意されているMSBuildではなく、dotnetコマンドを使ったスクリプトを記述します。といってこのように数行程度のスクリプトです。

dotnet --info
cd Chatwork.Service
dotnet restore
dotnet pack -c Debug --version-suffix $env:APPVEYOR_BUILD_VERSION
dotnet pack -c Release

デバッグのために--infoを出力した後は、プロジェクトディレクトリに移動して、NuGetのリストアー、そしてDebug構成とRelease構成でdonet packしてNuGetパッケージを作成しています。普段の自動ビルドはDebug構成のみ、タグのpushのときはRelease構成のみビルドすればいいのですが、条件分岐をさぼって両方実行しています。また、--version-suffixはNuGetパッケージを作成するとのバージョンサフィックスをコマンドから指定するオプションです。プロジェクトファイル(csproj)で指定しているVersionPrefixとここで指定したサフィックスがあわさってバージョンとなります。またenv:APPVEYOR_BUILD_VERSIONという環境変数を使ってGeneralタブで指定したバージョンを参照することができます。

docs.microsoft.com

CSharp.Chatwork.Api/Chatwork.Service.csproj at v0.6.2 · tanaka-takayoshi/CSharp.Chatwork.Api · GitHub

バージョン番号がciではじまっているのは、アルファベットを含むことでprerelease扱いにすることができるからです。

docs.microsoft.com

Debugビルドパッケージの開発用NuGetフィードへの登録

AppVeyorではプロジェクトごとにNuGetフィードが用意されていて、ArtifactタブでnupkgファイルをArtifactに指定すると、自動で登録してくれます。これとは別にアカウントごとに用意されたNuGetフィードもあって、こちらにpushするときは通常のNuGetリポジトリ同様、ApiKeyとServerを指定してdotnet nuget pushします。

f:id:tanaka733:20170531170032p:plain

リリース用のDeployment

開発用にはこれで以上ですが、リリース時にnuget.orgにpushするべきDeploymentタブで設定します。デフォルトだとビルドのたびにDeploymentが実行されるので、今回のようにタグがpushされたときのみDeployするには、Deployment ConditionでAPPVEYOR_REPO_TAGtrueの条件を追加しておきます。NuGetへのpushはNuGetというproviderが用意されているので、それを選択し、ApiKeyやpushするファイルを指定すればOKです。

f:id:tanaka733:20170531170135p:plain

まとめ

以前のVisual StudioのMSBuildをいろいろいじっていた時と比べると、dotnetコマンドだけで完結するのでだいぶシンプルになりました。AppVeyorではVisual Studio 2017のイメージに.NET Core SDKが入っているのでそれを使っていますが、実際にはVisual Studioは必要ないです。実際にこの設定でPRを作成すると自動ビルドが走って、Botがコメントしてくれます。

github.com

*1:設定で特定のブランチのみ、もしくは特定のブランチ以外も指定できる