在Azure DevOps Pipeline模板中使用变量

eh57zj3b  于 2023-05-29  发布在  其他
关注(0)|答案(4)|浏览(293)

我们有一个Azure DevOps管道模板集合,可以跨多个存储库重用。因此,我们希望有一个包含所有模板变量的文件。
回购结构看起来像这样

template repo
  ├── template-1.yml
  ├── template-2.yml
  └── variables.yml

project repo
  ├── ...
  └── azure-pipelines.yml

variables.yml看起来像这样

...
variables:
  foo: bar

template-1.yml中,我们将导入variables.yml,如下所述

variables:
- template: variables.yml

azure-pipelines.yml中,我们使用这样的模板

resources:
  repositories:
    - repository: build-scripts
      type: git
      name: project-name/build-scripts

steps:
  ...
  - template: template-1.yml@build-scripts

当我们现在尝试运行管道时,我们得到以下错误消息:

template-1.yml@build-scripts (Line: 10, Col: 1): Unexpected value 'variables'
xmq68pz9

xmq68pz91#

问题是因为您在步骤范围内使用了变量模板。而variables根本不存在于那个级别。这应该对你有用:

resources:
  repositories:
    - repository: build-scripts
      type: git
      name: project-name/build-scripts

variables:
  - template: template-1.yml@build-scripts

steps:
  ...

这可在任何可能使用变量的地方使用。例如,你可以这样使用它:

jobs:
- job: myJob
  timeoutInMinutes: 10
  variables:
  - template: template-1.yml  # Template reference
  pool:
    vmImage: 'ubuntu-16.04'
  steps:
  - script: echo My favorite vegetable is ${{ variables.favoriteVeggie }}.
iyfjxgzm

iyfjxgzm2#

如果你的模板文件只有variables,你可以参考Krzysztof Madej的答案。
如果您的模板文件同时具有variablessteps,如下所示,则只能由extends使用。

# File: template-1.yml
variables: ...

steps: ...

或者你可以在一个阶段中编写它们,如下所示。

# File: template-1.yml
stages:
- stage: {stage}
  variables: ...
  jobs:
  - job: {job}
    steps: ...

然后将其作为单独的阶段插入。

# azure-pipelines.yml
stages:
- stage: ...
- template: template-1.yml
wgeznvg7

wgeznvg73#

我认为在最初的解释中遗漏了一些东西:
第一:如果你在一个模板中引用变量,那么你必须确保你在调用它的时候扩展了这个模板。调用定义未扩展变量的模板将导致管道执行失败。

template-1.yml@build-scripts (Line: 10, Col: 1): Unexpected value 'variables'

第二:在多个模板中引用变量时,不要用途:

${{ variables.foo }} #even though this is seen in templates examples.

而是使用普通的变量语法

$(foo) #this works

因此,对于最初引用的示例,以下应该可以工作。
Variables.yml:

variables:
    foo: bar

template-1.yml:

variables:
- template: variables.yml
....
steps:
...
- task: CmdLine@2
  displayName: Display Variable
  inputs:
    script: |
      echo $(foo)

azure-pipelines.yml:

resources:
  repositories:
    - repository: build-scripts
      type: git
      name: project-name/build-scripts

extends:
  template: template-1.yml@build-scripts

template-2.yml

steps:
...
- task: CmdLine@2
  displayName: Display Variable
  inputs:
    script: |
      echo $(foo)
bakd9h0s

bakd9h0s4#

  • 这种方法可以帮助别人,所以我决定在这里发布。

对于这种情况,还有一种“变通方法”,可能有点“脏”,因为你需要在每次执行模板时显式地指定参数,如果你有很多参数要传递,这不是一个好主意。(实际上,有一种方法,阅读下面的改进版本)但是,如果你真的想要或者你没有那么多的参数,这应该工作:
其逻辑是:你在变量模板中有所有的参数,比如templates/vars.yml

variables:
  - name: myVar1
    value: MyValue1
  - name: myVar2
    value: MyValue2

因为你在变量中有你需要的一切,可能没有必要将变量导入模板本身,因为模板将在管道中执行,这将导入你的变量,你可以显式地替换它,如下面的例子:
templates/my-template-setup-env.yml的内容(里面没有变量):

steps:
  - script: |
      echo "$(myVar3)"

my-azure-pipeline.yml的内容(带导入变量模板):

name: my-cute-CI-name

trigger:
- main

pool:
  vmImage: ubuntu-18.04
  
variables:
  - template: templates/vars.yml # importing your variables from templates

    stages:
      - stage: RunTheStage
        displayName: 'Run first stage'
        jobs:
        - job: RunTheJob
          displayName: 'Run your job'
          steps:
            - template: templates/my-template-setup-env.yml # your template
               parameters:
                 myVar3: $(myVar1) # substitute value from vars.yml, so myVar1 will be used in templated and printed

改进版

但是,如果你在所有管道和模板中对参数和变量都有唯一的命名,你可以在模板使用过程中不显式地指定它,这也会起作用:
my-azure-pipeline.yml的编辑和缩短版本(如果模板中的变量和参数名称相同):

variables:
  - template: templates/vars.yml
...
      steps:
        - template: templates/my-template-setup-env.yml # env preparation
          # parameters:
          #   myVar2: $(myVar2) # you don't need to pass any parameters explicitly to the template since you have same name of variable

templates/my-template-setup-env.yml应该是这样的:

steps:
  - script: |
      echo "$(myVar2)" # not myVar3, since myVar3 is not in initial variables file templates/vars.yml

或者你也需要将剩余的变量(在第一个例子中是myVar3)添加到templates/vars.yml文件中。

相关问题