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

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

(Azure Pipelines) ビルドパイプラインの使用するリソースの値を表示する

Azure Pipelines ではパイプライン外でresourcesとして定義しているリソースの値があります。 例えば、repositoriesを使用すると別サービスのリポジトリをチェックアウトすることも可能になっており、他にもpipelinescontainersなどを利用することができます。

<resourcesスキーマ>

resources:
  pipelines: [ pipeline ]  
  builds: [ build ]
  repositories: [ repository ]
  containers: [ container ]
  packages: [ package ]
  webhooks: [ webhook ]

スキーマは以下のリンクから抜粋しています。

docs.microsoft.com

これらの値を定義することは簡単なのですが、どのようなプロパティがあり、どのような値が設定されているのかはドキュメントを読んでもイマイチピンときません。 今回は偶然?このリソースの値を表示する方法を見つけたので備忘録として残しておきます。

リソースって何?って方は以下のリンクを読んでください。

docs.microsoft.com

リソースの値を参照するyaml

結論から先に。 リソースの値を参照するには yaml で以下のように各リソースを JSON へ変換します。

variables:
  pipelineVar: $[ convertToJson(Pipeline) ]            # resources.pipeline properties
  resourcesVar: $[ convertToJson(resources) ]       # resources properties
  variablesData: $[ convertToJson(variables) ]       # variables properties

定義する場所は yaml のルートでもいいですし、stagejob配下でもいいです。

これを定義したビルドを実行すると、以下のようにログ画面からジョブ名→Job preparation parametersを選択するとリソースの値が JSON 形式で表示されます。

f:id:iyemon018:20211017174217p:plain

実際には以下のような値が表示されます。 今回はresources - repositoriesで別リポジトリを参照している yaml を利用しました。 なので、他のリソースの値は表示されていません。pipelinescontainersを設定している場合は同様にログに出力されます。

Job preparation parameters
Variables:
  variablesData:
    Parsing expression: <convertToJson(variables)>
    Evaluating: convertToJson(variables)
    Result: '{
  "resources.triggeringCategory": "",
  "resources.triggeringAlias": "",
  "variablesData": "$[ convertToJson(variables) ]",
  "pipelineVar": "$[ convertToJson(Pipeline) ]",
  "resourcesVar": "$[ convertToJson(resources) ]",
  "system": "build",
  "system.hosttype": "build",
  "system.servertype": "Hosted",
  "system.culture": "en-US",
  "system.collectionId": "xxxxxxx-xxxxxxx-xxxxx-xxxx-xxxx",
  "system.collectionUri": "https://dev.azure.com/<Organization>/",
  "system.teamFoundationCollectionUri": "https://dev.azure.com/<Organization>/",
  "system.taskDefinitionsUri": "https://dev.azure.com/<Organization>/",
  "system.pipelineStartTime": "2021-10-14 23:33:56+09:00",
  "system.teamProject": "Azure Pipelines Learning",
  "system.teamProjectId": "xxxxxxx-xxxxxxx-xxxxx-xxxx-xxxx",
  "system.definitionId": "21",
  "build.definitionName": "Azure Pipelines Learning",
  "build.definitionVersion": "1",
  "build.queuedBy": "<User Name>",
  "build.queuedById": "xxxxxxx-xxxxxxx-xxxxx-xxxx-xxxx",
  "build.requestedFor": "<User Name>",
  "build.requestedForId": "xxxxxxx-xxxxxxx-xxxxx-xxxx-xxxx",
  "build.requestedForEmail": "<User unique name>",
  "build.sourceVersion": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "build.sourceBranch": "refs/heads/master",
  "build.sourceBranchName": "master",
  "build.reason": "Manual",
  "system.pullRequest.isFork": "False",
  "system.jobParallelismTag": "Private",
  "system.enableAccessToken": "SecretVariable",
  "MSDEPLOY_HTTP_USER_AGENT": "VSTS_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "AZURE_HTTP_USER_AGENT": "VSTS_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "build.buildId": "1214",
  "build.buildUri": "vstfs:///Build/Build/1214",
  "build.buildNumber": "20211014.20",
  "build.containerId": "6470472",
  "system.isScheduled": "False",
  "system.definitionName": "Azure Pipelines Learning",
  "system.planId": "xxxxxxx-xxxxxxx-xxxxx-xxxx-xxxx",
  "system.timelineId": "xxxxxxx-xxxxxxx-xxxxx-xxxx-xxxx",
  "system.stageDisplayName": "__default",
  "system.stageId": "96ac2280-8cb4-5df5-99de-dd2da759617d",
  "system.stageName": "__default",
  "system.stageAttempt": "1",
  "system.phaseDisplayName": "",
  "system.phaseId": "d768f2aa-2c4b-5810-be30-11cbf757b796",
  "system.phaseName": "Job1",
  "system.phaseAttempt": "1"
}'
  pipelineVar:
    Parsing expression: <convertToJson(Pipeline)>
    Evaluating: convertToJson(Pipeline)
    Result: '{
  "startTime": "2021-10-14 23:33:56+09:00"
}'
  resourcesVar:
    Parsing expression: <convertToJson(resources)>
    Evaluating: convertToJson(resources)
    Result: '{
  "repositories": {
    "self": {
      "id": "xxxxxxx-xxxxxxx-xxxxx-xxxx-xxxx",
      "name": "Azure Pipelines Learning",
      "ref": "refs/heads/master",
      "type": "Git",
      "url": "https://dev.azure.com/<Organization>/Azure Pipelines Learning/_git/Azure Pipelines Learning"
    },
    "REPOS1": {
      "id": "xxxxxxx-xxxxxxx-xxxxx-xxxx-xxxx",
      "name": "Repos1",
      "ref": "refs/heads/master",
      "type": "git",
      "url": "https://dev.azure.com/<Organization>/Azure Pipelines Learning/_git/Repos1"
    }
  },
  "containers": {}
}'
ContinueOnError: False
TimeoutInMinutes: 60
CancelTimeoutInMinutes: 5
Expand:
  MaxConcurrency: 0

variables の値も表示できる

地味にありがたいのがsystembuildの値が表示されることですね。 variablesJSON で出力できるのでコンパイル時点で出力可能な変数については確認することができます。

ドキュメントに記載されていないプロパティも確認できる

例えば、resourcesのプロパティって何が定義されているのかドキュメントに記載されていません。 yaml を書く際のプロパティはスキーマのドキュメントにはあるのですが、値を参照するときの情報は皆無で必要になった場合は大変困ります。

このあたりにちょろっと.refsとかは書かれていますが、その程度です。

docs.microsoft.com

この手法を使えばreftype, urlなどが取得可能なことがわかります。

  resourcesVar:
    Parsing expression: <convertToJson(resources)>
    Evaluating: convertToJson(resources)
    Result: '{
  "repositories": {
    "self": {
      "id": "xxxxxxx-xxxxxxx-xxxxx-xxxx-xxxx",
      "name": "Azure Pipelines Learning",
      "ref": "refs/heads/master",
      "type": "Git",
      "url": "https://dev.azure.com/<Organization>/Azure Pipelines Learning/_git/Azure Pipelines Learning"
    },
    "REPOS1": {
      "id": "xxxxxxx-xxxxxxx-xxxxx-xxxx-xxxx",
      "name": "Repos1",
      "ref": "refs/heads/master",
      "type": "git",
      "url": "https://dev.azure.com/<Organization>/Azure Pipelines Learning/_git/Repos1"
    }
  },

取得できない値

  • Agent
  • Environment
  • Build, Systemの一部の値

定義済みの変数で上記の値は存在することはわかっていますが、この手法で参照することはできません。

docs.microsoft.com


variablesの各変数がどのような値を参照しているかなどは yaml の動作検証やバグ発生時に役立つかもしれません。 あとはresources - repositoriesで別リポジトリを参照している場合に、リポジトリの情報を通知したいシーンなどで、どのプロパティがどのような値か確認する場合にも利用できます(私の場合はこちらの調査で偶然この方法を見つけました)。