以下の内容はhttps://tech.guitarrapc.com/entry/2019/06/28/023710より取得しました。


Azure DevOps PipelineをYAMLで定義しよう

何度か挙げているAzure DevOps Pipelineですが、ずっとYAMLで紹介してきました。実際に私はAzure DevOpsにYAMLがPreviewで来てからずっとYAMLにしています。

これはほかのCIサービスも複数触っていたことからもYAMLでかけることに大きなメリットを見出していたからですが、改めてAzure DevOpsでPipelineをYAMLで定義するのをなぜススメるのか一部を書いておきます。

概要

ビルドは、そのプロジェクトを透明に維持するための大きなファクタの1つです。 コードとの密な連携を求められるCI/CDにおいて、ビルドの定義はコードと近いほうがイテレーションを短くできます。 YAMLはその手段の1つであり、現時点において大勢をなす方法の1つです。

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の利用方法が一緒に公開されているので困ることがほぼありません。

https://circleci.com/orbs/registry/

しかし タスクを配布しているMarket Placeにこの仕組みがないため、どのように利用するかのリファレンスはタスクの作者がGitHubで紹介しているか頼みです。で、GUIでタスクを設定するときの画面を見つつやることが多いという悪循環があります。

Azure DevOps でUnity Tools for Azure DevOpsタスクをLegacyパイプラインでUIから設定する

YAMLではこういう入力は見られないかというと、そうでもありません。 Azure DevOps Pipelineのサービス上でPipelineのEditを行うとUIからのUIから入力されます。*3 GUI -> YAMLがまとめて提供されているCIサービスって珍しいのでなかなか不思議な感覚です。

Azure DevOpsのPipeline 画面から Unity Tools for Azure DevOps を設定する

あるいは 以前のUIからのパイプラインを組んでおいてYAMLにExportという手もあります。 以前はカスタムタスクで必ずと言っていいほど使っていましたが、UIからのYAML入力ができてからは使わなくなりました。

Legacy Pipeline でUI上で組んだ設定をYAML でPreviewする

YAML で困ること

Azure DevOps PipelineのYAMLは、Multi Stage Pipelineがきて、一般的なSaaS型CIのYAML定義に比べてもかなり近づきました。 とはいえ、YAMLだけ未サポートだったり、アンドキュメントな挙動はあります。

そのあたりを見てみましょう。

Multi Stage Pipeline と失敗ジョブの再開

ありません。つらい。

CircleCIでいうところの、Workflow 中の失敗Jobだけの再実行 (Rerun from failed)はないので、ビルドをやり直すしかありません。

CircleCI のWorkflow 失敗時の選択

Failed Jobの再開くればいいんですけど。

Reference variable などの未サポート機能

Reference VariableはYAMLでは定義できません。 しかし、タスクが出力変数を設定しているなら、タスクのname:を設定することで後続にて利用できます。

こういった未サポート機能でも、なんかやる方法があったりします。アンドキュメントですが。

適当にフィードバックの各種やGitHub Issueをみるといいでしょう。

サポートを受け、フィードバックを提供する

https://github.com/microsoft/azure-pipelines-yaml

リリースと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: を省いたときのタスク実行時の表示

結果、DisplayName: を設定することになり、ビルド定義が冗長になっていくことが多いでしょう。

一方のCircleCIでは、ビルドタスクに名前をつけず、YAMLをなるべく最小限にしても困りません。 ビルドステップに名前を使えなかった時に、実行ログのstep名にはコマンドがそのまま名称になるからです。

CircleCIでステップの名称を付けないと、ステップの実行内容がそのまま表示される

こういう細かいところが、まだまだ改善の余地を感じます。

キャッシュ機能

AzureDevOpsには現状ビルドstepのキャッシュ機能はありません。 これがこないと毎ビルドでパッケージを復元したり無駄極まりありません。

Peeviewでくるらしいので待ちましょう。 キャッシュが来る場合、CircleCIのキャッシュのようにキーによる世代ハンドリングをしたいところです。 これが来ないとかなりアレなので。

おわりに

YAML定義は、Multi Stage Pipelineが来るまではリリース含めてどうするか、厳しいと言わざるを得ませんでした。 しかし、Multi Stage Pipelineが来て、ジョブの定義をより強力に記述できるようになったことでだいぶんよくなりました。

もしAzure DevOps Pipelineを使うなら、YAML一択です。

*1:CircleCIのWorkflowに相当

*2:CirclecIでいうCommandやJobに相当

*3:あくまで入力値だけで一度YAMLにいれたものの編集では開きません




以上の内容はhttps://tech.guitarrapc.com/entry/2019/06/28/023710より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14