简体   繁体   English

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

[英]Use variables in Azure DevOps Pipeline templates

We have a collection of Azure DevOps pipeline templates that we re-use across multiple repositories.我们收集了 Azure 个 DevOps 管道模板,我们可以在多个存储库中重复使用这些模板。 Therefore we wanted to have a file that contains variables for all of our templates.因此,我们希望有一个包含所有模板变量的文件。

The repo structure looks like this回购结构看起来像这样

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

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

The variables.yml looks like this variables.yml看起来像这样

...
variables:
  foo: bar

In template-1.yml we are importing the variables.yml as described in heretemplate-1.yml中,我们正在导入variables.yml ,如此所述

variables:
- template: variables.yml

In the azure-pipelines.yml we are using the template like thisazure-pipelines.yml中,我们使用这样的模板

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

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

When we now try to run the pipeline, we get the following error message:当我们现在尝试运行管道时,我们收到以下错误消息:

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

The issue is because you used variable template at steps scope.问题是因为您在步骤范围内使用了变量模板。 And variables simply doesnt' exists at that level. variables根本不存在于那个级别。 This should work for you:这应该适合你:

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

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

steps:
  ...

this is available to use at any place where variables are possible to use.这可以在任何可以使用变量的地方使用。 So for instance you can use this in that way:因此,例如,您可以以这种方式使用它:

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 }}.

If your template file only has variables , you can refer to Krzysztof Madej's answer.如果你的模板文件只有variables ,你可以参考 Krzysztof Madej 的回答。

If your template file has both variables and steps as shown below, it can only be used by extends .如果您的模板文件具有如下所示的variablessteps ,则它只能由extends 使用

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

steps: ...

Or you can write them in a stage, as shown below.或者你可以在一个阶段中编写它们,如下所示。

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

Then insert it as a separate stage.然后将其作为单独的阶段插入。

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

Replying as I think there was something missed in the original explanations:回复我认为原来的解释中遗漏了一些东西:

First: If you are referencing variables in a template then you must ensure that you are extending that template when you call it.第一:如果您在模板中引用变量,那么您必须确保在调用它时扩展该模板。 Calling a template that defines variables that is not extended will result in a failed pipeline execution.调用定义未扩展变量的模板将导致管道执行失败。

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

Second: When referencing variables in multiple templates do not use:第二:在多个模板中引用变量时不要使用:

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

but rather use the normal variable syntax而是使用普通的变量语法

$(foo) #this works 

So for the originally reference example the following should work.因此,对于最初的参考示例,以下内容应该有效。

Variables.yml:变量.yml:

  variables:
    foo: bar

template-1.yml:模板 1.yml:

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

azure-pipelines.yml: 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模板2.yml

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

This approach can help someone, so I decided to post it here.这种方法可以帮助某人,所以我决定在这里发布。

One more kind of "workaround" for that case, maybe a bit "dirty" since you need to specify the parameters explicitly each time you execute template, which is not a good idea if you have a lot of parameters to pass.这种情况的另一种“解决方法”,可能有点“脏”,因为每次执行模板时都需要明确指定参数,如果要传递很多参数,这不是一个好主意。 (actually, there is a way, read below improved version) But, if you really want or you have not that much parameters, this should work: (实际上,有一种方法,请阅读以下改进版本)但是,如果您真的想要或没有那么多参数,这应该可行:

the logic is: you have all your parameters in variables template, like templates/vars.yml :逻辑是:您在变量模板中拥有所有参数,例如templates/vars.yml

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

and since you have everything you need in the variables, probably there is no need to importing variables into template itself, because template will be executed in pipeline, which will have your variables imported and you can substitute it explicitly, like in the example below:并且由于您在变量中拥有所需的一切,因此可能无需将变量导入模板本身,因为模板将在管道中执行,这将导入您的变量,您可以显式替换它,如下例所示:

templates/my-template-setup-env.yml 's content (without variables inside it): templates/my-template-setup-env.yml的内容(里面没有变量):

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

my-azure-pipeline.yml 's content (with importing variables template): 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

Improved version改良版

But, if you have unique naming of your params and variables across all pipelines and templates, you are in safe to not specify it explicitly during template usage, that will work as well:但是,如果您在所有管道和模板中对参数和变量进行了唯一命名,则在模板使用期间不明确指定它是安全的,这也将起作用:

edited and shortened version of my-azure-pipeline.yml (in case you have the same name of your variable and parameter in template):已编辑和缩短的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 then should be like this: templates/my-template-setup-env.yml应该是这样的:

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

or you need to add remaining variables (myVar3 in our first case) into templates/vars.yml file as well.或者您还需要将剩余的变量(在我们的第一种情况下为templates/vars.yml )添加到templates/vars.yml文件中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM