在Azure DevOps管道模板中使用变量

时间:2020-09-16 10:07:14

标签: azure azure-devops yaml azure-devops-pipelines

我们有一个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中,我们按照here所述导入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'

3 个答案:

答案 0 :(得分:2)

问题是因为您在步骤作用域使用了变量模板。 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 }}.

答案 1 :(得分:2)

如果模板文件仅包含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

答案 2 :(得分:0)

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

这种情况的另一种“解决方法”,可能有点“脏”,因为您每次执行模板时都需要明确指定参数,如果您有很多参数要传递,这不是一个好主意。 (实际上,有一种方法,请阅读以下改进版本)但是,如果您真的想要或没有那么多参数,这应该可行:

逻辑是:您在变量模板中拥有所有参数,例如 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 文件中。