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

Cannot override global variables in included Taskfiles since 3.36.0 #1588

Open
MarioSchwalbe opened this issue Apr 9, 2024 · 7 comments
Open
Labels
state: needs triage Waiting to be triaged by a maintainer.

Comments

@MarioSchwalbe
Copy link
Contributor

MarioSchwalbe commented Apr 9, 2024

  • Task version: 3.36.0
  • Operating system: Linux (probably others)
  • Experiments enabled: none

We need 2 task files (see https://taskfile.dev/usage/#vars-of-included-taskfiles):

Taskfile.yml:

version: '3'

includes:
  subA:
    taskfile: DockerBuild.yml

  subB:
    taskfile: DockerBuild.yml
    vars:
      DOCKER_IMAGE: imageOfB

tasks:
  default:
    cmds:
      - task: subA:show   # Uses the default value.
      - task: subB:show   # Used to be `imageOfB`. Now is `default_image`.

and DockerBuild.yml:

version: '3'

vars:
  DOCKER_IMAGE: default_image

tasks:
  show:
    cmds:
      - echo "DOCKER_IMAGE = {{.DOCKER_IMAGE}}"

Since version 3.36.0 I get:

$ task
task: [subA:show] echo "DOCKER_IMAGE = default_image"
DOCKER_IMAGE = default_image
task: [subB:show] echo "DOCKER_IMAGE = default_image"
DOCKER_IMAGE = default_image

In previous versions it was possible to override variables when including taskfiles changing the second case to:

$ task
task: [subA:show] echo "DOCKER_IMAGE = default_image"
DOCKER_IMAGE = default_image
task: [subB:show] echo "DOCKER_IMAGE = imageOfB"
DOCKER_IMAGE = imageOfB

Is this an intended change? And if yes, how would we implement something like that instead?

@task-bot task-bot added the state: needs triage Waiting to be triaged by a maintainer. label Apr 9, 2024
@glenvan
Copy link

glenvan commented Apr 9, 2024

Same issue here.

Passing in a variable with the intention of overriding a variable that is defined in the top-level vars: object of the included file no longer replaces the variable's value.

The workaround is to use the default function, as in the test data for (the possible cause) #1533:

vars:
  DOCKER_IMAGE: {{ .DOCKER_IMAGE | default "default_image" }}

@jclasley
Copy link

FWIW, using an anchor in the vars works:

# taskfile A

version: 3

vars:
  VAR: "bar"

tasks:
  echo:
    cmds:
      - echo {{ .VAR }}
---
# taskfile B
version: 3

def: &var
  VAR: "foo"

includes: 
  A: 
    taskfile: Taskfile.A.yaml

tasks:
  echo:
    cmds:
      - task: A:echo
        vars:
          *var

which outputs "foo"
but that same command with a merge override is then overridden

# ...
 echo:
    cmds:
      - task: A:echo
        vars:
           <<: *var

echos "bar"


If you're like me and have a bunch of variables that you don't want to hardcode over and over, the anchors proved to be a sufficient workaround.

@pd93
Copy link
Member

pd93 commented Apr 16, 2024

This looks to be related to #1533. I was slightly worried about the potential for this to break Taskfiles at the time. I'll take a more detailed look at this soon.

Edit: It was decided that this was a bugfix at the time and that the proper way was to use | default as suggested by @glenvan.

As an aside - @MarioSchwalbe, I see that in your repro example, you are including the same Taskfile twice with two different namespaces. Is this a common setup for you? The upcoming DAG changes (#1563) which will be included in the next release would actually restrict this functionality. It's not something that I thought would be useful or common at the time. Please let me know if you think otherwise.

@pd93
Copy link
Member

pd93 commented Apr 16, 2024

@jclasley I'm not able to reproduce your second example. Firstly, PREFIX: {{ .PREFIX }} causes an error since the template is not quoted, but even if I fix this, I do not observe the random behaviour you're describing. In fact, I get identical behaviour on v3.35.1 and v3.36.0.

I have assumed that you have a file named Taskfile.yml in each of the folders: a, b and c as opposed to files with these names. Can you confirm this? Also, your include to ./internal is from the same directory. Does this mean you have an internal directory inside each of a, b and c?

Could you please double check that your example properly reproduces the behaviour you're seeing and update it if necessary. Thanks.

@jclasley
Copy link

@pd93 you're right, the second one works as expected. I thought that it was the inclusions that were messing up, but now I realize I was declaring global vars in each child taskfile. Thank you for double-checking!

@MarioSchwalbe
Copy link
Contributor Author

MarioSchwalbe commented Apr 18, 2024

As an aside - @MarioSchwalbe, I see that in your repro example, you are including the same Taskfile twice with two different namespaces. Is this a common setup for you? The upcoming DAG changes (#1563) which will be included in the next release would actually restrict this functionality. It's not something that I thought would be useful or common at the time. Please let me know if you think otherwise.

Yes. This is definitely important as I'm using some sort of utility Taskfile to build multiple projects (in subdirectories) from within a Taskfile in the top-level directory.

Additionally, these run in different directories like so:

includes:
  subA:
    taskfile: DockerBuild.yml
    dir: subA

  subB:
    taskfile: DockerBuild.yml
    dir: subB
    vars:
      DOCKER_IMAGE: imageOfB

@vmaerten
Copy link
Collaborator

Hi @pd93

I have the exact same use case than @MarioSchwalbe. I've opened an issue to discuss / track it :

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
state: needs triage Waiting to be triaged by a maintainer.
Projects
None yet
Development

No branches or pull requests

6 participants