可変グループを持つAzure DevOps yamlパイプラインの変数でIF ELSEを使用するにはどうすればよいですか?


8

変数グループに加えて2つの値のいずれかを変数に割り当てようとしていますが、IF ELSEの使用方法に関する参照が見つかりません。

基本的に、このジャーキンロジックを紺碧のDevOpsに変換する必要があります。

ジェンキンス

if (branch = 'master') { 
   env = 'a'
} else if (branch = 'dev'){
    env ='b'
}

次の1つの参照を見つけましたが、変数セクションに変数グループがない場合、これは機能するようです。

https://stackoverflow.com/a/57532526/5862540

しかし、私のパイプラインでは、シークレット用の可変グループが既にあるので、名前/値の規則を使用する必要があり、例はexpected a mappingor A mapping was not expectedまたはorのようなエラーでは機能しませんUnexpected value 'env'

variables:
- group: my-global
- name: env
  value:
    ${{ if eq(variables['Build.SourceBranchName'], 'master') }}: 
      env: a
    ${{ if eq(variables['Build.SourceBranchName'], 'dev') }}: 
      env: b

または

variables:
- group: my-global
- name: env
  value:
    ${{ if eq(variables['Build.SourceBranchName'], 'master') }}: a
    ${{ if eq(variables['Build.SourceBranchName'], 'dev') }}: b


現在の回避策の1つは、変数セクションと式を必要なすべてのジョブにコピーすることです。しかし、私はそれを単純なグローバル変数にしたいと思います。
kevmando

回答:


1

今のところ、name/value構文変数と条件変数の値でカスタマイズするタスクを使用する必要があると思います。ごname/value指摘のとおり、構文のオブジェクト構造は式の解析を中断するように見えます。

私にとって、以下はかなりクリーンな実装であり、それをパイプラインから抽象化したい場合、使用する多くのパイプラインの単純なテンプレートは、中央の「グローバル」ロケーションの要求を満たすはずです。

variables:
  - group: FakeVarGroup
  - name: env
    value: dev

steps:
  - powershell: |
      if ($env:Build_SourceBranchName -eq 'master') {
        Write-Host ##vso[task.setvariable variable=env;isOutput=true]a
        return
      } else {
        Write-Host ##vso[task.setvariable variable=env;isOutput=true]b
      }      
    displayName: "Set Env Value"

提案をありがとう。私はここから同様の解決策を見たと思いますが、ステップを追加せずにもっと簡単な解決策があることを望んでいるので、試していません。MSサポートにも質問したので、解決策がない場合は、これを試してみます。
kevmando

私はMSサポートと電子メールを交換しましたが、彼らはこの回避策を提案してしまい、MS開発者コミュニティの機能提案を入力するように求めてきました。だから私はこれを答えとしてマークします。
kevmando

0

私の知る限り、条件付きブランチビルドを作成する最良の方法は、複雑な「if-else」を実装する代わりに、YAMLで「トリガー」を使用することです。また、はるかに安全であり、CI変数に依存する代わりに、ブランチトリガーをより明示的に制御できます。

例:

# specific branch build 
jobs:
- job: buildmaster
  pool:
    vmImage: 'vs2017-win2016'
  trigger:
    - master

  steps:
  - script: |
      echo "trigger for master branch"

- job: buildfeature
  pool:
    vmImage: 'vs2017-win2016'
  trigger:
    - feature

  steps:
  - script: |
      echo "trigger for feature branch"

分岐を含むトリガーと除外するトリガーを設定するには、分岐を含むトリガーと除外するトリガーのより複雑な構文を使用できます。

例:

# specific branch build
trigger:
  branches:
    include:
    - master
    - releases/*
    exclude:
    - releases/1.*

triggerYAML でのAzure DevOps Pipelinesの公式ドキュメントは次のとおりです 。AzurePipelines YAMLトリガードキュメント

更新1

ここでコメントを再投稿しますが、追加の注意事項があります。CI変数間のジャグリングの複雑さは、トリガーを備えた1つのYAMLにマルチジョブを持つよりも維持しにくいため、異なるパイプラインを考えていました。トリガー付きのマルチジョブを持つことは、ブランチ管理に関する明確な区別と規定を強制することにもなります。トリガーと条件付きブランチのインクルージョンは、これらの保守性の利点により、私のチームによって1年間使用されてきました。

遠慮なくご意見をお聞かせください。どのスクリプトでも、どのセッションが現在セッション中であるかを確認し、その後さらにアクションを実行するためのロジックを組み込んでいるのは、アドホックソリューションに似ています。そして、これは私のチームと私に以前メンテナンス問題を与えました。

特に、組み込みロジックが他のブランチをチェックすることで成長する傾向がある場合、ブランチ間の明確な分離よりも後で複雑さがさらに複雑になります。また、YAMLファイルを長期間維持する場合は、さまざまなブランチに明確な規定とロードマップが必要です。冗長性は避けられませんが、特定のロジックを分離する意図は、保守性のために長期的にはより多くを支払うことになります。

これが私が私の答えで枝の包含と除外も強調する理由です:)


提案に感謝しますが、私のパイプラインはすでに別の目的でもトリガーを使用しています。(正直に言うと、トリガー機能自体はJenkinsに比べて柔軟性が低いように感じられます。複製されたpr / branchビルドをキャンセルするなどの条件を実装するのは難しいです。)また、ブランチごとに1つの値を変更するためだけに、同じジョブを繰り返します。(変数セクションを繰り返すことで回避策を
講じる

ジェンキンスではないので、おそらく「ジェンキンス」の枠から考える必要があるかもしれませんが、チームは明らかな利点のない新しいパイプラインを望んでいません。
kevmando

新しいパイプライン?いいえ。そのYAMLは1つのファイルに含まれているため、多くのブランチにサービスを提供できる1つのパイプラインで使用できます
Eriawan Kusumawardhono

新しいパイプラインとは、新しいワークフローが以前のワークフローとは異なる働きをすることです。このトピックとは関係ありませんが、ここで言及されて以来、より多くのトリガーオプションがあります。
kevmando

OPは、ブランチの値に基づいてビルドをトリガーする方法を尋ねていません。質問されたのは、パイプラインがトリガーされるコンテキストに基づいて変数値を条件付きにする方法です。実際の質問にあなたの解決策を適用すると、OPは2つのパイプラインを作成する必要があります1)トリガー=マスター&env = a 2)トリガー= dev&env = b。
Josh Gust
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.