Azure Pipeline:在一个模板中设置变量,在另一个模板中的表达式中使用它
Azure Pipeline: Setting variable in one template, use it in expression in another
我试图达到的目标:
- 在名为
set-variable.yml
的模板 1 中设置变量 featureName
- 将变量 featureName 作为参数传递给名为
check-variable.yml
的模板 2
- 检查模板 2 的编译时表达式中的 featureName 参数是否为空。
pipeline.yml:
trigger:
- '*' # Run on all Branches
pool:
vmImage: ubuntu-latest
stages:
- stage: test1
jobs:
- job: test1
steps:
- template: set-variable.yml
- template: check-variable.yml
parameters:
featureName: $(setVariables.featureName)
设置-variable.yml:
steps:
- script: |
featureName=''
echo "##vso[task.setvariable variable=featureName;isOutput=true]$featureName"
displayName: Set variable
name: setVariables
检查-variable.yml:
parameters:
- name: featureName
type: string
default: ''
steps:
- ${{ if ne(parameters.featureName, '') }}:
- script: |
echo "This should not be executed, but it is!"
displayName: "featureName != ''"
问题是,check-variable.yml
中的步骤 featureName != ''
被执行了,即使我将 set-variables.yml
模板中的 featureName
变量设置为空。
(将变量 featureName
作为参数传递给模板 check-variable.yml
有效,请参阅下面的调试尝试)
=== 调试 1 ===
出于调试目的,我用一些调试任务扩展了 check-variable.yml
。
检查-variable.yml:
parameters:
- name: featureName
type: string
default: ''
steps:
- script: |
echo "Check feature"
echo "- featureNameDotted: [${{ parameters.featureName }}]"
echo "- featureNameArray: [${{ parameters['featureName'] }}]"
echo "- featureNameEnvDotted: [$featureNameEnvDotted]"
echo "- featureNameEnvArray: [$featureNameEnvArray]"
echo "- json: [${{ convertToJson(parameters.featureName) }}]"
echo "- length: [${{ length(parameters.featureName) }}]"
echo
if [[ -z $featureNameEnvDotted ]]; then
echo "featureNameEnvDotted is (empty or null)"
else
echo "featureNameEnvDotted not (empty or null)"
fi
echo
if [[ $featureNameEnvDotted = '' ]]; then
echo "featureNameEnvDotted = ''"
else
echo "featureNameEnvDotted != ''"
fi
echo
if [[ $featureNameEnvDotted = 'hello' ]]; then
echo "featureNameEnvDotted = 'hello'"
else
echo "featureNameEnvDotted != 'hello'"
fi
env:
featureNameEnvDotted: ${{ parameters.featureName }}
featureNameEnvArray: ${{ parameters['featureName'] }}
displayName: "Debug: All"
- ${{ if eq(parameters.featureName, '') }}:
- script: |
echo
env:
featureName: ${{ parameters.featureName }}
displayName: "Debug: Empty!!"
- ${{ if ne(parameters.featureName, '') }}:
- script: |
echo
env:
featureName: ${{ parameters.featureName }}
displayName: "Debug: Not empty!!"
- ${{ if eq(parameters.featureName, 'hello') }}:
- script: |
echo
env:
featureName: ${{ parameters.featureName }}
displayName: "Debug: Equals 'hello'"
- ${{ if ne(parameters.featureName, '') }}:
- script: |
echo "This should not be executed, but it is!"
displayName: "featureName != ''"
任务Debug: All
的输出是:
Check feature
- featureNameDotted: []
- featureNameArray: []
- featureNameEnvDotted: []
- featureNameEnvArray: []
- json: []
- length: [27]
featureNameEnvDotted is (empty or null)
featureNameEnvDotted = ''
featureNameEnvDotted != 'hello'
bash 如果一切正常。 featureName 为空且不是 'hello'。 'length'一个没看懂
并执行以下任务:
- 设置变量
- 调试:全部
- 调试:不为空!!
- 特征名称 != ''
为什么任务 Debug: Not empty!!
和 featureName != ''
得到执行,但任务 Debug: Empty!!
没有? featureName 参数 IMO 为空!
=== 调试 2 ===
我 check-variable.yml
保持不变。但是我在 set-variable.yml
模板中将 featureName
设置为值“hello”。有了这个我想检查变量 featureName
是否正确传递给模板的参数 check-variable.yml
设置-variable.yml:
steps:
- script: |
featureName='hello'
echo "##vso[task.setvariable variable=featureName;isOutput=true]$featureName"
displayName: Set variable
name: setVariables
任务Debug: All
的输出是:
Check feature
- featureNameDotted: [hello]
- featureNameArray: [hello]
- featureNameEnvDotted: [hello]
- featureNameEnvArray: [hello]
- json: [hello]
- length: [27]
featureNameEnvDotted not (empty or null)
featureNameEnvDotted != ''
featureNameEnvDotted = 'hello'
这又看起来不错。该参数确实包含值 'hello' 并且 if 看起来不错(不过,长度我不明白)。
这里是要执行的任务列表:
- 设置变量
- 调试:全部
- 调试:不为空!!
- 特征名称 != ''
为什么Debug: Equals 'hello'
没有执行?
parameters.featureName
包含类似于值 'hello' 的内容,但它不完全是字符串 'hello'。我是不是做错了什么?
我发现了问题。评估为 27 的 ${{ length(parameters.featureName) }}
将我推向了正确的方向。 27 是传递给模板 check-variable.yml
.
的字符串 $(setVariables.featureName)
的长度
这可以用我在 check-variable.yml
中输入的以下表达式进行测试:
- ${{ if eq(parameters.featureName, '$(setVariables.featureName)') }}:
- script: |
echo
env:
featureName: ${{ parameters.featureName }}
displayName: "Debug: Equals 'dollar(setVariables.featureName)'"
这总是在设置 featureName 或为空时执行。
我认为发生的情况是,当在模板内评估 ${{ ... }}
等编译时表达式时,参数 featureName 被评估为 $(setVariables.featureName)
。 ${{ if ... }}
表达式以及带有 ${{ parameters...}}
的脚本任务就是这种情况。在对 ${{ ... }}
表达式求值后,它开始执行脚本任务。它在那里找到变量 $(setVariables.featureName)
并对其求值。但是对于带有 if 语句的编译时表达式,永远不会对 $(setVariables.featureName)
进行求值。在那里它只需要变量的名称。
所以为了让它工作,我做了一个工作,我在脚本任务中设置了一个变量,并使用任务条件来评估它。
check-variable.yml:
parameters:
- name: featureName
type: string
default: ''
steps:
- script: |
echo "##vso[task.setvariable variable=featureName]${{ parameters.featureName }}"
displayName: "Set featureName var"
- script: |
echo "Only execute me when featureName is not empty"
displayName: "featureName != ''"
condition: and(succeeded(), ne(variables.featureName, ''))
我试图达到的目标:
- 在名为
set-variable.yml
的模板 1 中设置变量 featureName
- 将变量 featureName 作为参数传递给名为
check-variable.yml
的模板 2
- 检查模板 2 的编译时表达式中的 featureName 参数是否为空。
pipeline.yml:
trigger:
- '*' # Run on all Branches
pool:
vmImage: ubuntu-latest
stages:
- stage: test1
jobs:
- job: test1
steps:
- template: set-variable.yml
- template: check-variable.yml
parameters:
featureName: $(setVariables.featureName)
设置-variable.yml:
steps:
- script: |
featureName=''
echo "##vso[task.setvariable variable=featureName;isOutput=true]$featureName"
displayName: Set variable
name: setVariables
检查-variable.yml:
parameters:
- name: featureName
type: string
default: ''
steps:
- ${{ if ne(parameters.featureName, '') }}:
- script: |
echo "This should not be executed, but it is!"
displayName: "featureName != ''"
问题是,check-variable.yml
中的步骤 featureName != ''
被执行了,即使我将 set-variables.yml
模板中的 featureName
变量设置为空。
(将变量 featureName
作为参数传递给模板 check-variable.yml
有效,请参阅下面的调试尝试)
=== 调试 1 ===
出于调试目的,我用一些调试任务扩展了 check-variable.yml
。
检查-variable.yml:
parameters:
- name: featureName
type: string
default: ''
steps:
- script: |
echo "Check feature"
echo "- featureNameDotted: [${{ parameters.featureName }}]"
echo "- featureNameArray: [${{ parameters['featureName'] }}]"
echo "- featureNameEnvDotted: [$featureNameEnvDotted]"
echo "- featureNameEnvArray: [$featureNameEnvArray]"
echo "- json: [${{ convertToJson(parameters.featureName) }}]"
echo "- length: [${{ length(parameters.featureName) }}]"
echo
if [[ -z $featureNameEnvDotted ]]; then
echo "featureNameEnvDotted is (empty or null)"
else
echo "featureNameEnvDotted not (empty or null)"
fi
echo
if [[ $featureNameEnvDotted = '' ]]; then
echo "featureNameEnvDotted = ''"
else
echo "featureNameEnvDotted != ''"
fi
echo
if [[ $featureNameEnvDotted = 'hello' ]]; then
echo "featureNameEnvDotted = 'hello'"
else
echo "featureNameEnvDotted != 'hello'"
fi
env:
featureNameEnvDotted: ${{ parameters.featureName }}
featureNameEnvArray: ${{ parameters['featureName'] }}
displayName: "Debug: All"
- ${{ if eq(parameters.featureName, '') }}:
- script: |
echo
env:
featureName: ${{ parameters.featureName }}
displayName: "Debug: Empty!!"
- ${{ if ne(parameters.featureName, '') }}:
- script: |
echo
env:
featureName: ${{ parameters.featureName }}
displayName: "Debug: Not empty!!"
- ${{ if eq(parameters.featureName, 'hello') }}:
- script: |
echo
env:
featureName: ${{ parameters.featureName }}
displayName: "Debug: Equals 'hello'"
- ${{ if ne(parameters.featureName, '') }}:
- script: |
echo "This should not be executed, but it is!"
displayName: "featureName != ''"
任务Debug: All
的输出是:
Check feature
- featureNameDotted: []
- featureNameArray: []
- featureNameEnvDotted: []
- featureNameEnvArray: []
- json: []
- length: [27]
featureNameEnvDotted is (empty or null)
featureNameEnvDotted = ''
featureNameEnvDotted != 'hello'
bash 如果一切正常。 featureName 为空且不是 'hello'。 'length'一个没看懂
并执行以下任务:
- 设置变量
- 调试:全部
- 调试:不为空!!
- 特征名称 != ''
为什么任务 Debug: Not empty!!
和 featureName != ''
得到执行,但任务 Debug: Empty!!
没有? featureName 参数 IMO 为空!
=== 调试 2 ===
我 check-variable.yml
保持不变。但是我在 set-variable.yml
模板中将 featureName
设置为值“hello”。有了这个我想检查变量 featureName
是否正确传递给模板的参数 check-variable.yml
设置-variable.yml:
steps:
- script: |
featureName='hello'
echo "##vso[task.setvariable variable=featureName;isOutput=true]$featureName"
displayName: Set variable
name: setVariables
任务Debug: All
的输出是:
Check feature
- featureNameDotted: [hello]
- featureNameArray: [hello]
- featureNameEnvDotted: [hello]
- featureNameEnvArray: [hello]
- json: [hello]
- length: [27]
featureNameEnvDotted not (empty or null)
featureNameEnvDotted != ''
featureNameEnvDotted = 'hello'
这又看起来不错。该参数确实包含值 'hello' 并且 if 看起来不错(不过,长度我不明白)。
这里是要执行的任务列表:
- 设置变量
- 调试:全部
- 调试:不为空!!
- 特征名称 != ''
为什么Debug: Equals 'hello'
没有执行?
parameters.featureName
包含类似于值 'hello' 的内容,但它不完全是字符串 'hello'。我是不是做错了什么?
我发现了问题。评估为 27 的 ${{ length(parameters.featureName) }}
将我推向了正确的方向。 27 是传递给模板 check-variable.yml
.
$(setVariables.featureName)
的长度
这可以用我在 check-variable.yml
中输入的以下表达式进行测试:
- ${{ if eq(parameters.featureName, '$(setVariables.featureName)') }}:
- script: |
echo
env:
featureName: ${{ parameters.featureName }}
displayName: "Debug: Equals 'dollar(setVariables.featureName)'"
这总是在设置 featureName 或为空时执行。
我认为发生的情况是,当在模板内评估 ${{ ... }}
等编译时表达式时,参数 featureName 被评估为 $(setVariables.featureName)
。 ${{ if ... }}
表达式以及带有 ${{ parameters...}}
的脚本任务就是这种情况。在对 ${{ ... }}
表达式求值后,它开始执行脚本任务。它在那里找到变量 $(setVariables.featureName)
并对其求值。但是对于带有 if 语句的编译时表达式,永远不会对 $(setVariables.featureName)
进行求值。在那里它只需要变量的名称。
所以为了让它工作,我做了一个工作,我在脚本任务中设置了一个变量,并使用任务条件来评估它。
check-variable.yml:
parameters:
- name: featureName
type: string
default: ''
steps:
- script: |
echo "##vso[task.setvariable variable=featureName]${{ parameters.featureName }}"
displayName: "Set featureName var"
- script: |
echo "Only execute me when featureName is not empty"
displayName: "featureName != ''"
condition: and(succeeded(), ne(variables.featureName, ''))