-
Notifications
You must be signed in to change notification settings - Fork 852
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
YAML - Support conditions for templates #1749
Comments
this is supported: - ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
- template: sharedstep.yml@templates
parameters:
value: true |
Yes I agree a template would work but the enhancement request is that I be able to use a condition like I can for every other item I can put into a step. Conditions are far easier to write and read then template expressions and the overly complex syntax you have to use to avoid errors. |
i seem to be experiencing some issues with this kind of conditions in yaml`s child yaml:
parent yaml:
$(updateArmTemplate) is a variable settable at queue time, with default value 'true' and around the yaml i also have a default value when declaring this parameter in the child yaml the behavior is that it doesn't get executed although on 'true' |
I came across this issue yesterday and tried the solution mentioned above and I can confirm that it does not work, the way it is described. Here's part of my yaml:
The same syntax ( |
We have created a new repository for all YAML related issues, please move the current issue to there. |
@ericsciple |
@vtbassmatt to redirect |
@MathieuBuisson you could do something like this: # azure-pipelines.yml
steps:
- script: <generate output variable here>
name: deciderstep
- template: sharedstep.yml@templates
parameters:
doTheThing: $[ variables['deciderstep.myVariable'] ]
# sharedstep.yml
steps:
- script: echo Sometimes this happens!
condition: eq(parameters.doTheThing, 'true')
- script: echo Sometimes this also happens!
condition: eq(parameters.doTheThing, 'true') (N.B. I didn't test that, just wrote it from memory, and it may need some tweaking.) It's not as elegant as a conditional inclusion of the template, but does get the scenario working. |
I tried that and got an error message stating that "parameters" was unknown here.
but this did not execute because the parameter was only evaluated as literally Or to be accurate in what I tested, in case it matters, I did not use an output variable but a simple one, and just used this syntax: |
I'm using the suggested approach for optional execution of a template: And get: /build-templates/steps/node-app-deploy-steps.yml@templates: (Line: 76, Col: 19, Idx: 3882) - (Line: 76, Col: 19, Idx: 3882): Mapping values are not allowed in this context. If I remove the parameters, then the pipeline compiles, but obviously I need my parameters! This is a template within a template calling another template - don't know if that's significant. Update: It was an indentation issue - 'parameters' should be at the same level as the 'template' keyword. I'll leave it here so that future generations can laugh at my mistake :-) |
Nothing to laugh at -- YAML is a confusing beast 😁 Glad you got it solved. |
Hello @vtbassmat , I am trying to use the example you provided however having some issue such as the one described by @afeblot. When you use the parameter syntax as below
|
Hi @pbalexlear - we're not doing product support through GitHub issues anymore. Please open a ticket on Developer Community with your scenario. I'll note a couple of things that may unblock you here:
|
Thanks for coming back to me @vtbassmatt , I understand what you are saying however, the default action when a parameter is passed into a template seems to be to wrap it as a string or at least this is how it is displayed in the pipeline output as if it is treating it as a string value of the expression. I understand what you are saying that if the value of a parameter was an expression and wasn't wrapped as a string it would be substituted in and evaluated at runtime, however because the system is wrapping the parameter as a string it doesn't behave this way. I did manage to find a solution by passing the name of the variable as the value of the parameter, which isn't a solution I like but does work functionally. If you could advise on how to prevent the system wrapping the expression as a string that would be greatly appreciated. As I have resolved my issue although through an unideal solution I won't raise a ticket, but would appreciate it if you could advise on the above. Thanks. Alex |
Your comment made me dig in and try this, and I realized I had a couple of dumb mistakes. The below two files are complete and work the way you'd expect: # azure-pipelines.yml
pool: { vmImage: ubuntu-latest }
steps:
- checkout: none
- bash: |
echo Creating output variable...
echo '##vso[task.setVariable variable=myVariable;isOutput=true]true' # also tested with 'false'
name: deciderstep
- template: template.yml
parameters:
doTheThing: eq(variables['deciderstep.myVariable'], true) # template.yml
parameters:
doTheThing: 'false'
steps:
- script: echo This always happens!
displayName: Always
- script: echo Sometimes this happens!
condition: ${{ parameters.doTheThing }}
displayName: Only if true |
Thanks @vtbassmatt , that's perfect and exactly what I was looking for, thanks very much for taking the time to look into this. |
This would be much simpler and less surprising if the condition element was supported on template. |
Useful formulation for suppressing things, for example when you know that part of the environment isn't ready is:
|
Thanks! I confirm that the following code is working as expected. - ${{ if eq(variables['byPassSlotDeploymentOnDev'], 'true') }}:
- template: pipeline/web-deploy.yml@Templates
parameters:
type: $(type)
env: dev
appRoleSuffix: $(appRoleSuffix)
appRgSuffix: $(appRgSuffix)
zipDeploymentFilePath: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip |
I need to set a variable using the statement: And then insert or not a template.
Any suggestions ? |
@JamesDLD |
this is a pipeline limitation, the |
This is it! I think I got an example of what people is asking for (be creative to implement more custom conditions):
parameters:
- name: condition
displayName: When should send the message
default: always
values:
- always
- canceled
- failed
- succeeded
- succeededOrFailed
steps:
- pwsh: |
$status = "$(Agent.JobStatus)"
Write-Host "This step was executed because the Pipeline Job Status is $status and the condition is ${{ parameters.condition }}"
displayName: Echo if condition ${{ parameters.condition }} match
condition: ${{ parameters.condition }}()
stages:
- stage: TEST
jobs:
- job: TEST
steps:
- checkout: self
- template: condition-example.yml
parameters:
condition: succeeded
- pwsh: throw "TEST"
displayName: Throw an error
- template: condition-example.yml
parameters:
condition: succeeded
- template: condition-example.yml
parameters:
condition: failed
- template: condition-example.yml
parameters:
condition: succeededOrFailed
- template: condition-example.yml
parameters:
condition: always
- template: condition-example.yml
parameters:
condition: canceled |
I wanted to do the below, but can't and I don't see an alternative :'(
|
/ci/my.yml (Line: x, Col: y): Unrecognized value: 'succeeded'. Located at position 5 within expression: and(succeeded(), eq('${{ parameters.things}}', 'true')). For more help, refer to https://go.microsoft.com/fwlink/?linkid=842996 |
This looks like simple ask. If we dig deeper, I don't how it can be implemented. The template expands during compile time, if we use runtime condition to a template, does that mean we don't want the template to expand during compile time? or we want the condition to applied to the expanded elements? Not sure, how this can be added to product. Also I really see the benefits of have runtime template selection. This can also cause the pipeline to keep expanding and not know when it will end. |
yes, it is, just skip the template as unexpanded (implies some azure pipeline GUI change), and mark it in gray, |
The feedback is given to the community in past and the request was closed due to lack of response from community. I have recreated the same so please vote to make sure, it gains right attention. |
You can implement something like the following:
parameters:
- name: condition
displayName: When to create the tag and push it
type: string
default: succeeded()
steps:
- bash: echo "${{ parameters.condition }}"
displayName: Step with inherited condition from template parameter ${{ parameters.condition }}
condition: ${{ parameters.condition }}
- bash: |
echo "${{ parameters.condition }}"
echo "Executed because parameter condition is true or branch is main"
displayName: Another step with inherited condition from template parameter ${{ parameters.condition }}
condition: or(${{ parameters.condition }}, eq(variables['Build.SourceBranch'], 'refs/heads/main')) pipeline.yml ...
- template: mytemplate.yml
parameters:
condition: always() |
What if I want to run different templates based on conditions within the same job? For example.
|
is this working for you? |
Hi @copdips thanks for the reply!
No it doesn't, with the following error message Here's more code context:
The variable Want I want to do is to use different step/task level templates based on a variable (preferable) or parameter. |
AFIK, and based on the other comments in this issue, no ... |
Have you tried trouble shooting?
Queuing a build generates an error. Unexpected value 'condition'.
Agent Version and Platform
Version of your agent? 2.102.0/2.100.1/...
OS of the machine running the agent? Windows
VSTS Type and Version
VSTS
If VisualStudio.com, what is your account name? https://fsmb.visualstudio.com
What's not working?
I am trying to set up a YAML build. We have a lot of builds and our existing definitions use task groups. I am moving the task group logic into a template so they can be shared across build definitions. The templates are stored in a separate repository. All this is working correctly.
There is one step that shouldn't execute when it is a PR build so I tried to do this.
The build won't queue because of the error - Unexpected value 'condition'.
It would be nice if templates could be conditional like tasks are. Right now the workaround would be to either use a parameter or specify the condition inside the template but the template may not always know the correct condition to use.
Agent and Worker's Diagnostic Logs
It is not queuing so there is no log.
Related Repositories
Please ensure you are logging issues to the correct repository in order to get the best support.
If you are hitting a generic issue about VSTS/TFS, please report it to the Developer Community
The text was updated successfully, but these errors were encountered: