Skip to content
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] Calculate value for task input using conditions #1727

Closed
t3mi opened this issue Jul 24, 2018 · 10 comments
Closed

[YAML] Calculate value for task input using conditions #1727

t3mi opened this issue Jul 24, 2018 · 10 comments
Assignees

Comments

@t3mi
Copy link

t3mi commented Jul 24, 2018

Have you tried trouble shooting?

Couldn't queue the build

Agent Version and Platform

Version of your agent?
2.136.1

OS of the machine running the agent?
CentOS 7 x64 7.5

VSTS Type and Version

VSTS

What's not working?

According to templateexpressions there is a possibility to use task condition for the templates. I've tried to use next value for one of the task input ${{ and(not(parameters.force), not(parameters.override)) }} and it wasn't calculated properly. Limiting value to just one function ${{ not(parameters.force) }} throws the same error. I want to have task enabled/disabled depending on the value of two parameters. Is it possible?

Error in VSTS while trying to queue a build:
build.package.yml (Line: 13, Col: 14): Unexpected type: 'System.Boolean',build.package.yml (Line: 13, Col: 14): Expected a Boolean value. Actual value: ''

# .vsts-ci.yml
name: $(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.rr)
queue: PrivatePool
steps:
  - template: build.package.yml
    parameters:
      force: true
# build.package.yml
parameters:
  force: false
  override: false

steps:
  - checkout: self
    clean: true

  - task: DownloadBuildArtifacts@0
    displayName: Download Build Artifacts
    condition: and(succeeded(), in(variables['build.reason'], 'Manual', 'Schedule'))
    continueOnError: true
    enabled: ${{ and(not(parameters.force), not(parameters.override)) }}
    inputs:
      buildType: specific
      downloadType: specific
@t3mi t3mi changed the title YAML Calculate value for task input using conditions [YAML] Calculate value for task input using conditions Jul 24, 2018
@ericsciple
Copy link
Contributor

Thanks I was able to repro the bug. Here is a workaround:

# build.package.yml
parameters:
  force: false
  override: false

steps:
  - checkout: self
    clean: true
  - ${{ if and(ne(parameters.force, 'false'), ne(parameters.override, 'false')) }}
    - task: DownloadBuildArtifacts@0
      displayName: Download Build Artifacts
      condition: and(succeeded(), in(variables['build.reason'], 'Manual', 'Schedule'))
      continueOnError: true
      inputs:
        buildType: specific
        downloadType: specific

@ericsciple
Copy link
Contributor

In the expressions, all scalar parameters are interepreted as strings and not is truthy. So not will only evaluate to true if the string is empty.

@ericsciple
Copy link
Contributor

...so I switched your expression to use ne

@t3mi
Copy link
Author

t3mi commented Jul 25, 2018

@ericsciple thanks. Workaround is working I've just added ':' to the end of the line.

So not will only evaluate to true if the string is empty.

So that means, for example with ${{ not(parameters.force) }}:
parameters.force - would be a string
output of not(parameters.force) - would be a boolean
output of ${{ not(parameters.force) }} - would be a string converted from boolean, e.g. empty string for a True?

P.S. Should this issue remain opened or can be closed?

@ericsciple
Copy link
Contributor

@t3mi let's leave it open for now.

Your assessment regarding not(parameters.force) is accurate. I realize now there is a gap in the docs. I need to add an example to describe this behavior.

I found the bug. Thanks for reporting this. When I get a fix in, and an ETA when it will be deployed, I'll update the work item here and likely close it then.

@ericsciple ericsciple self-assigned this Jul 25, 2018
@ggirard07
Copy link

@ericsciple just to be sure I follow you on what is going on here based on feedback from @t3mi :

parameters.force - would be a string

Does it means parameters in templates don't follow their YAML type?
Instead, simple values are always string and complex values are always objects. Even if I declare a parameter as force: false it will be first evaluated as a string (ie always equivalent to declaring force: 'false').
Actually I am not sure I properly get the meaning of not is truthy (sorry for my lack of English 😄)

output of ${{ not(parameters.force) }} - would be a string converted from boolean

Does it means expanded expression will always be of type string?
In that case I do not really understand the meaning of the provided error message Unexpected type: 'System.Boolean' whereas the actual type of the expanded expression is a string...

Lastly, are those assertion going to be default behaviors for GA?

@ericsciple
Copy link
Contributor

@ggirard07 That's correct. As far as we're concerned when we are building the yaml DOM, everything is string, sequence, or mapping.

Expressions support Boolean, number, string, datetime, and complex types. But when the expressions is evaluated the result should always be convert to string, sequence, or mapping. (currently there is a bug, because Boolean is not getting converted to string; i'm working on a fix right now)

@ericsciple
Copy link
Contributor

@vtbassmatt fyi, there are good details in this issue we need to capture in the docs. i'll create a user story on the internal backlog and paste relevant portions from this issue.

@TingluoHuang
Copy link
Contributor

We have created a new repository for all YAML related issues, please move the current issue to there.
https://github.com/Microsoft/azure-pipelines-yaml

@TingluoHuang
Copy link
Contributor

move to microsoft/azure-pipelines-yaml#29

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants