やる気駆動型エンジニアの備忘録

WPF(XAML+C#)の話題を中心に.NET/Android/CI やたまに趣味に関するブログです

(Azure Pipelines)手動トリガー時に Agent.Name を指定して実行する方法

ビルドタスクを Self hosted な環境で実行する場合に、たまに手動トリガーを使うことがあります。 何らかの障害原因調査などで特定のエージェントに対してビルドを実行するようなケースはあります。 そんな要件を満たすにはランタイム パラメータを使用します。

ここでは、ランタイム パラメータを使用して手動トリガー実行時にエージェント名を指定する方法についてまとめています。

Azure Pipelines の Runtime Parameters については以下のリンクを参照してください。

docs.microsoft.com

通常の手動トリガー

手動トリガーを使用する場合、パイプラインを実行しようとしても Demands を入力することができないため、特定のエージェントで実行することはできません。 Classic editor だと Demands を設定できるんですが、yaml ではそういった手段は存在しません。

# azure-pipelines.yml

trigger: none

jobs:
- job:

  steps:
  - script: echo Hello, world!
    displayName: 'Run a one-line script'

シンプルな yaml ですが、手動でパイプラインを実行しようとするとこのように Demands を入力することはできません。

f:id:iyemon018:20211004233150p:plain

Runtime parameters

ランタイムパラメータは、パイプラインを実行する際に値を渡すことができます。 この機能を使うことでパイプラインの実行時にユーザーが動作を制御することができます。

イメージとしては以下のリンクが参考になると思います。

docs.microsoft.com

Runtime parameters を使用して Agent.Name を指定する

パイプライン実行時に Agent.Name を指定するには以下のように yaml を書き換えます。 ポイントはparametersdemands部分です。

# azure-pipelines.yml

trigger: none

parameters:
  - name: agentName
    displayName: エージェント名(Option)
    type: string
    default: 'any'

jobs:
- job:
  pool:
   name: Self hosted pool
   demands:
   - ${{ if ne(parameters.agentName, 'any') }}:
     - Agent.Name -equals ${{ parameters.agentName }}

  steps:
  - script: echo Hello, world!
    displayName: 'Run a one-line script'

今回は、通常であればエージェントを指定することがなく、特定のシチュエーションのみエージェントを指定するような想定にしました。 人間が使用することを考慮してdisplayNameで分かりやすい表示名をつけておきましょう。 日本語も使用できるのでわかりやすさ重視で良いと思います。

f:id:iyemon018:20211004234059p:plain

parameters.agentNameの初期値はanyとし、それ以外の値が入力されていればエージェント名と判断しています。 なお、ランタイムパラメータは必須入力のため、defaultに何も指定しなかったり空文字だと、以下のように Run ボタンが非活性になります。 分かりやすいdefaultの値を設定しておくのが良いでしょう。

f:id:iyemon018:20211004234252p:plain

ルートの demands でランタイムパラメータを使用することはできない

yaml のルートにあるpool - demandsでランタイムパラメータを使おうとしても以下のようなメッセージが出力されて実行できません。 何故かはよくわかってないのですが、必ずjobあるいはstage配下のdemadsを使用しましょう。

/azure-pipelines.yml (Line: 16, Col: 5): A mapping was not expected

# azure-pipelines.yml

trigger: none

parameters:
  - name: agentName
    displayName: エージェント名(Option)
    type: string

# ここに書いても動かない。
pool:
  name: Self hosted pool
  demands:
  - ${{ if ne(parameters.agentName, 'any') }}:
    - Agent.Name -equals ${{ parameters.agentName }}

jobs:
- job:

  steps:
  - script: echo Hello, world!
    displayName: 'Run a one-line script'

手動トリガーはリリース時などによく使用されると思いますが、状況に応じて動作を制御したい場合にランタイムパラメータは必須になってきます。 他にもvaluesで選択肢を予め設定しておくこともできるので、要件に合わせて柔軟に対応しましょう。