My ci_pipeline.yml
contains the following:
- stage: DeployDEV
pool:
vmImage: 'windows-latest'
variables:
- group: [REDACTED]
- name: test_var
value: firstval
jobs:
- job: BuildDeploy
displayName: "REDACTED"
steps:
- script: echo "test_var = $(test_var)"
displayName: first variable pass
- bash: echo "##vso[task.setvariable variable=test_var]secondValue"
displayName: set new variable value
- script: echo "test_var = $(test_var)"
displayName: second variable pass
name: Env
displayName: "Extract Source Branch Name"
- template: pipeline_templates/ci_pipeline_templates/build_deploy_dev.yml
parameters:
testvar: $(test_var)
and in the build_deploy_dev.yml
template:
parameters:
- name: testvar
jobs:
- job: Test
displayName: "Testjob"
steps:
- script: echo "test_var=${{ parameters.testvar }}"
name: TestVar
displayName: 'test'
I need to be able to modify the variable in the main yml file BEFORE passing it into the template. However, test_var
still remains as firstval
. What am I doing wrong? It seems like the change is successful in the main yml file. The second variable pass script displays test_var=secondValue
. How to make the change be permanent so the template can have it ?
CodePudding user response:
Unfortunately you cannot use variables set during runtime, ie. $test_var
, as parameters for templates. Think of templates less like functions and more like snippets. The pipeline essentially swaps the guts of the template for the reference to the template and all parameters are evaluated at that time and swapped.
So when you set $test_var
to 'firstval', the template is evaluated at that time and the parameter is set to 'firstval' as well. Then when you set $test_var
later in the yaml, it is too late. See the documentation below:
https://docs.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops#context
It may feel dirty to reuse code but unfortunately this would be the recommended solution.
- stage: DeployDEV
pool:
vmImage: 'windows-latest'
variables:
- group: [REDACTED]
- name: test_var
value: firstval
jobs:
- job: BuildDeploy
displayName: "REDACTED"
steps:
- script: echo "test_var = $(test_var)"
displayName: first variable pass
- bash: echo "##vso[task.setvariable variable=test_var]secondValue"
displayName: set new variable value
- script: echo "test_var = $(test_var)"
displayName: second variable pass
- job: Test
displayName: "Testjob"
steps:
- script: echo "test_var=$(test_var)"
name: TestVar
displayName: 'test'
CodePudding user response:
As stated above: Parameters are evaluated in compile time. So, using parameters won't solve your problem, however you can create a new variable as an output and make your template job dependent from the job which generates a new variable afterwards you can use it in your template as follows:
ci_pipeline.yml
- stage: DeployDEV
pool:
vmImage: 'windows-latest'
variables:
- group: [REDACTED]
- name: test_var
value: firstval
jobs:
- job: BuildDeploy
displayName: "REDACTED"
steps:
- script: echo "test_var = $(test_var)"
displayName: first variable pass
- bash: echo "##vso[task.setvariable variable=new_var;isOutput=true]SomeValue"
displayName: set new variable value
name: SetMyVariable
name: Env
displayName: "Extract Source Branch Name"
- template: pipeline_templates/ci_pipeline_templates/build_deploy_dev.yml
Then in your build_deploy_dev.yml you can use the variable you've created previously:
jobs:
- job: Test
variables:
test_var: $[ dependencies.BuildDeploy.outputs['SetMyVariable.new_var'] ]
displayName: "Testjob"
dependsOn: BuildDeploy
steps:
- script: echo "test_var=$(test_var)"
name: TestVar
displayName: 'test'
Note that you can still leverage your $(test_var) for instance to check whether it has the value 'firstValue' and then in case positive you create the 'newVar' and use it on the other job, you could even use the value of $(test_var) in your 'newVar' and use the value which you previously set:
- bash: echo "##vso[task.setvariable variable=new_var]$(test_var)"
displayName: set new variable value
In this way you can dynamically 'change' the behavior of your pipeline and keep your template file.