何度か挙げている Azure DevOps Pipeline ですが、ずっとYAML で紹介してきたかと思います。
実際に私はAzure DevOps にYAML がPreview で来てからずっとYAML にしています。
これはほかのCIサービスも複数触っていたことからもYAML でかけることに大きなメリットを見出していたからですが、改めてAzure DevOps でPipeline をYAML で定義するのをなぜススメるのか一部を書いておきます。
目次
TL;DR
ビルドは、そのプロジェクトを透明に維持するための大きなファクタの1つです。 コードとの密な連携を求められるCI/CD において、ビルドの定義はコードと近いほうがイテレーションを短くできます。 YAML はその手段の一つであり、現時点において大勢をなす方法の一つです。
Pipeline first な開発をするためにも、開発者自身が主体的にビルドを組めるYAML はいい方法になるでしょう。
個人的には、YAML で定義できないビルドサービスはなるべく避けたほうがいいと判断します。
YAML 定義のメリット
YAMLで定義できるということは、そのプロジェクトのビルド設定を、そのプロジェクトのリポジトリに置けます。結果として、アプリケーションの変更で生じたビルドの変更も適用しやすく素早くビルドを開発に合わせられるメリットがあります。(Config as Code の1つと言われたりするようですね)
Azure Pipeline でもYAML で定義することで、どのようなビルドをしているかが定義でわかります。
また、Multi Stage Pipeline でワークフローっぽく複数のジョブの連携を1つのYAMLで定義できるようになっています。*1 GUI では難しかった同じような内容のビルドでパラメータが違うだけ、というのも、YAMLならJob/Step Template を使うことで、なんども同じ定義をせず再利用が可能です。*2
YAMLでパイプラインを組みたいときの流れ
YAML Pieplineを選択してビルドパイプラインを設定しましょう。
Azure DevOps Pipeline は、後付けでYAML定義がきました。 そのため、ほかのYAML定義ができるCI サービス に比べると処理をタスクという単位で設定することが多い傾向にあります。 このタスクの中身は、Pipeline で実行したい特定の操作を TypeScript で定義してMarket Store で公開、利用するものです。 CircleCI だとOrb が近いでしょう。
Orbがそうであるように、タスクを利用するときはそのタスクに渡すパラメーターを知る必要があります。 この時、Orbなら Explore Orbsで定義が探すとOrbの利用方法が一緒に公開されているので困ることがほぼありません。
しかし タスクを配布している Market Place にこの仕組みがないため、どのように利用するかのリファレンスはタスクの作者がGitHub で紹介しているか頼みです。で、GUI でタスクを設定するときの画面を見つつやることが多いという悪循環があります。
YAML ではこういう入力は見れないでしょうか? そうでもありません。 Azure DevOps Pipeline のサービス上で Pipeline の Edit を行うとUIからのUIからの入力がされます。*3 GUI -> YAML がまとめて提供されているCIサービスって珍しいのでなかなか不思議な感覚です。
あるいは 以前のUIからのパイプラインを組んでおいてYAML にExport という手もあります。 以前はカスタムタスクで必ずと言っていいほど使っていましたが、UI からのYAML入力ができてからは使わなくなりました。
YAML で困ること
Azure DevOps Pipeline のYAML は、Multi Stage Pipeline がきて、一般的なSaaS 型CI のYAML 定義に比べてもかなり近づきました。 とはいえ、YAML だけ未サポートだったり、アンドキュメントな挙動はあります。
そのあたりを見てみましょう。
Multi Stage Pipeline と失敗ジョブの再開
ありません。つらい。
CircleCI でいうところの、Workflow 中の失敗Job だけの再実行 (Rerun from failed)はないので、ビルドをやり直すしかありません。
Failed Job の再開くればいいんですけど。
Reference variable などの未サポート機能
Reference Variable はYAMLでは定義できません。
しかし、タスクが出力変数を設定しているなら、タスクの name:
を設定することで後続で利用できます。
こういった未サポート機能でも、なんかやる方法があったりします。アンドキュメントですが。
適当にフィードバックの各種や GitHub Issue をみるといいでしょう。
リリースとYAML定義
ReleaseにはYAMLがありません。そのためReleaseはどうしようかと思ってしばらくしましたが、2019/6にMulti Stage Pipeline がきました。
これでRelease はオワコンっぽい雰囲気しつつあります。
ただしDeployment Group が YAML では扱えないのでそこは置いておきましょう。Gate 機能も使えないので困ったものです。
一方でビルドトリガーに関しては、Multi Stage Pipeline + Pipeline Artifact (Build Artifact はLegacyです) で checkout: none
にして、Condition をかければいいでしょう。
approve などのGate と Deployment Group だけ困りますが、ほかまぁ何とかなります。
Display Name のうざさ
Azure DevOps では ビルドタスクで DisplayName:
をつけなかった場合、ステップの名称はタスクの名称
になります。
Comand Line タスクなら、CmdLine となってしまい、実行しているコマンドが自動的に付けられません。
結果、DisplayName:
を設定することになり、ビルド定義が冗長になっていくことが多いでしょう。
一方のCircleCI では、ビルドタスクに名前をつけず、YAMLをなるべく最小限にしても困りません。
ビルドステップに名前を使えなかった時に、実行ログのstep 名にはコマンドがそのまま名称になる
からです。
こういう細かいところが、まだまだ改善の余地を感じます。
キャッシュ機能
AzureDevOps には現状ビルドstep のキャッシュ機能はありません。 これがこないと毎ビルドでパッケージを復元したり無駄極まりありません。
Peeview でくるらしいので待ちましょう。 キャッシュが来る場合、CircleCI のキャッシュのようにキーによる世代ハンドリングをしたいところです。 これが来ないとかなりアレなので。
おわりに
YAML 定義は、Multi Stage Pipeline が来るまではリリース含めてどうするか、厳しいと言わざるを得ませんでした。 しかし、Multi Stage Pipeline が来て、ジョブの定義をより強力に記述できるようになったことでだいぶんよくなりました。
もし Azure DevOps Pipeline を使うなら、YAML 一択です。