在Azure DevOps Pipeline模板中使用变量

16
我们有一系列的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'
4个回答

15
问题是你在 steps 范围使用了变量模板,而 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 }}.

不幸的是它不起作用。我需要在模板中使用变量来表示步骤,因为我想将这些步骤包含在另一个流水线的job.steps部分中。因此,要求是我可以在这样的步骤模板中访问在变量模板中定义的变量。 - Michael Lihs
您可以在任何可用变量的级别上使用变量模板。我的编辑对您有所帮助吗? - Krzysztof Madej

9
如果你的模板文件只包含 变量,你可以参考 Krzysztof Madej 的答案。
如果你的模板文件既包含 变量,也包含如下所示的 步骤,则只能通过 扩展 来使用它。
# 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

回复一下,因为我认为原始解释中有一些遗漏的内容:

首先: 如果您在模板中引用变量,则必须确保在调用它时扩展该模板。调用未扩展定义变量的模板将导致管道执行失败。

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)

1
有没有办法让它工作?我想在步骤名称中使用变量值,这只能通过编译时表达式实现。但由于某种原因,在编译时缺少变量...请勿使用 ${{ variables.foo }}。 - Mike

1

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

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接