しばやん雑記

ASP.NET Core とメイドさんが大好きなフリーランスのプログラマーのブログ

AppVeyor を捨てて Azure Pipelines に全て移行した話

4 年ほど使ってきた AppVeyor にあった 30 近いプロジェクトを今日、隅田川花火大会という外に出たくないタイミングで断捨離しつつ全て Azure Pipelines に移行しました。

最近は Azure Pipelines をガッツリ弄っていたので、すんなりと移行出来ました。*1

貴重な Windows に対応した CI SaaS としてお世話になったので感謝しかありません。とはいえ、最近は Azure Pipelines の方がメリットが多くなってきたので、徐々に移行は進めてきました。

AppVeyor を捨てた理由

アップデートが少なくなった

単純に AppVeyor の今後が怪しいと感じるようになってきたからです。2018 年は毎月こまめに VM イメージがアップデートされてきましたが、今年に入ってからはアップデート頻度が急に下がりました。

GitHub の方を見ると Ubuntu と Visual Studio 2019 についてはアップデートされているようでしたが、こういった部分の情報発信が滞ってくると注意信号という感じです。

ログが見にくい

AppVeyor のログは Azure Pipelines や CircleCI のようにステップ毎にグループ化されることはなく、フラットに出力されるだけです。

ビルドログが長い場合や、NuGet パッケージの復元のようなログが多く出る場合は確認しにくかったです。どのコマンドまで処理されたかは、ログをじっくり眺めて確認しないといけないのは辛いです。

プライベートリポジトリを使う場合は割と高い

Basic Plan を $29 で契約しても、使えるプライベートリポジトリは 1 つだけという割と鬼仕様です。

2 年ほどは $59 の Pro Plan を契約して使ってきましたが、最近はちょっと価格に見合わないと考えるようになってきました。そもそも Azure Pipelines はプライベートリポジトリが無料で使えましたし。

Pull Request 作成時の挙動が嫌いだった

デフォルトの設定だと Pull Request を作成した場合に pr と branch の両方のトリガーが走ってしまい、2 度同じコミットがビルドされるという無駄な挙動になっていました。

最後の方にはビルドブランチを master のみに制限すれば解決すると分かりましたが、ビルドに 10 分近くかかる C++ のプロジェクトの時には本当に困らされました。

移行の決め手になったのは AppVeyor ではどうしてもビルドが通らない C++ のプロジェクトが、Azure Pipelines だとすんなりと通ってしまったことでした。

AppVeyor / Azure Pipelines の比較

代表的な部分について自分の知識の整理も兼ねて、違いをまとめておきました。

基本的な機能

全体的に Azure Pipelines の方が機能が多くて、制限が緩くなっています。並列ジョブが OSS 向けだと多く使えるので、各プラットフォーム向けに並列でビルドして高速化出来ます。

AppVeyor Azure Pipelines
対応プラットフォーム Windows / Linux Windows / Linux / macOS
公開リポジトリ 1 並列ジョブが無料 10 並列ジョブまで無料
プライベートリポジトリ 有償 1 並列ジョブ / 1800 分まで無料
ビルド定義 YAML / GUI YAML / GUI
マシンサイズ 2 cores 6 GB / 2 cores 7.5 GB 2 cores 7 GB (Standard_DS2_v2)
コンテナー対応 Docker 対応 Docker + Container job 対応
ビルドキャッシュ 対応 対応(プレビュー)
パッケージリポジトリ NuGet NuGet / npm / Maven / Python / Universal

パッケージリポジトリは Azure Artifacts になりますが、ほぼ一体なので同じように扱っています。

詳細はそれぞれのサービスのドキュメントを見てもらえれば良いです。

対応プラットフォームが多く、プライベートリポジトリのビルドも 1 並列であれば利用できるのが Azure Pipelines のメリットですね。なおビルド速度は AppVeyor は基本ベアメタル使ってるので、Azure Pipelines よりは全体的に早いです。

Build Agent で利用可能なコンポーネント

インストールされているコンポーネントはドキュメントや GitHub 上で公開されています。AppVeyor は Visual Studio 2019 のイメージも用意されていますが、ドキュメントには記載がないです。

Azure Pipelines の場合は Container job を使って、独自に用意した Docker Image を使ってビルド実行も出来るので、環境の自由度は高いですね。インストーラータスクも各言語向けに用意されているので便利。

苦労した点など

Service Connection の扱い

Azure Pipelines の面倒な部分として、Azure Resource Manager や NuGet へのアクセスはそれぞれ Service Connection を作成しておいて、それをタスクから参照という形を多くとります。

Service Connection は組織で共有できず、プロジェクト毎に作らないといけないので、いくつかのリポジトリは同じプロジェクトにまとめてしまいました。

f:id:shiba-yan:20190728163705p:plain

Azure Storage ぐらいアクセスキーで雑に利用したかったですが、ARM 必須だったので仕方ないです。

ディレクトリの違い

利用するタスクによって起点となるパスが異なることが多いので、ディレクトリについては注意しつつ書く必要があります。AppVeyor ではソースがチェックアウトされたディレクトリだけなのでシンプルでした。

よく使ったディレクトリとしては以下の 3 つです。一部同じように見えますが、ドキュメント上は違うような説明もあるので、正直かなり混乱します。

  • Build.SourcesDirectory
  • System.DefaultWorkingDirectory
  • Pipeline.Workspace

Pipeline Artifacts を使う場合には、特に気を使う必要があったので注意したいです。

移行したリポジトリ例

移行したリポジトリは全て GitHub で公開しているものなので、パイプライン定義が気になった方は自由に参照してください。C# / C++ 中心にビルドしています。

最後の方に作業したリポジトリの方が定義が洗練されているので、時間がある時に同期を取るつもりです。

*1:AppVeyor がシンプルな機能しか持っていないというのもある