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

Global variables and included taskfile #696

Closed
aliculPix4D opened this issue Apr 1, 2022 · 11 comments
Closed

Global variables and included taskfile #696

aliculPix4D opened this issue Apr 1, 2022 · 11 comments

Comments

@aliculPix4D
Copy link

  • Task version: v3.9.0
  • Operating System: ubuntu 20.04

Very similar issue: #618

Hi, first thank you for the great tool. I would like to report what my team and I consider a bug (unexpected behavior) and to check your opinion on the topic.

Consider the following setup:

  • first Taskfile in the root directory: Taskfile.yml
version: '3'

includes:
  imported: import/Taskfile.yml

vars:
  custom_value: root

tasks:
  print_var:
    cmds:
      - echo {{.custom_value}}
  • second in the sub directory: import and included from the root Taskfile
version: '3'

vars:
  custom_value: included

tasks:
  print_var:
    cmds:
      - echo {{.custom_value}}

Running the following commands:

>  task imported:print_var
task: [imported:print_var] echo included
included
> task print_var  
task: [print_var] echo included
included

While our expectation were more in line with the following:

>  task imported:print_var
task: [imported:print_var] echo included
included
> task print_var  
task: [print_var] echo root
root

where the root task would print the value set in root Taskfile.

Thanks for looking at this issue.

@ghostsquad
Copy link
Contributor

For clarification, your expectation is that root vars take precedence over vars of the same name coming from an include?

@ghostsquad
Copy link
Contributor

Try upgrading to 3.12 and check out this part of the docs:

https://taskfile.dev/#/usage?id=vars-of-included-taskfiles

See if that helps.

@aliculPix4D
Copy link
Author

For clarification, your expectation is that root vars take precedence over vars of the same name coming from an include?

Yes, I did not expect that variable custom_value: root configured in root Taskfile (the one that include all others) will be ignored just because some other included Taskfile had the variable with the same name configured.

Try upgrading to 3.12 and check out this part of the docs

Yes, we are aware of this new feature in 3.12 but it seems as a workaround for the real issue, hence we wanted to first check if the above is wanted behavior or do you consider it as a bug as we do?

@ghostsquad
Copy link
Contributor

it seems as a workaround for the real issue, hence we wanted to first check if the above is wanted behavior or do you consider it as a bug as we do?

This is not a bug. It was a conscious design decision.

The reason why is that the goal is to allow you to essentially use included task files like composable pieces. Being able to create multiple namespaces and such using the same file (via an include).

The style guide and other documentation likely should be updated to show some examples and specific scenarios that you may encounter, and how best to structure your Taskfile's.

@ghostsquad
Copy link
Contributor

But I don't want to leave you hanging with this answer. The examples in your original post, though very good minimal reproducible example files, don't demonstrate the use case you have. Would you mind providing more detailed information on your use case, and I can help guide you to a working solution/pattern?

@marco-m-pix4d
Copy link
Contributor

@ghostsquad thanks for your help! I am in the same team as @aliculPix4D and we are using a fork I did to fix a problem with signal propagation to subprocesses (see #479). At this point, I think it makes more sense for us to upgrade the fork to 3.12 (given the changes in var handling you mention) and then continue this discussion.

@pd93
Copy link
Member

pd93 commented Oct 15, 2022

@aliculPix4D @marco-m-pix4d How did you get on with 3.12? Are you still having issues, or can this be closed?

@pd93 pd93 removed the v4 label Oct 15, 2022
@marco-m-pix4d
Copy link
Contributor

hello @pd93, we switched to using Task upstream (as opposed to our fork), because Task handles signal propagation better since 3.13.

Regarding this specific issue, @aliculPix4D could you please confirm wether we are still seeing this behavior, and if yes, would it be possible to "demostrate the use case we have" as requested in #696 (comment) ? Thanks :-)

@aliculPix4D
Copy link
Author

aliculPix4D commented Oct 31, 2022

First sorry for the late reply. I had a look at the issue again.

Here is my summary:

  1. We don't see this issue anymore in our case because we have implemented a workaround:
  • in local tests and pre-commit hook we ensure that sub task files (the one not in the root of the repository) do not declare variables
  • the consequence of our workaround is that no sub task file can be run independently on its own and we must run task from repository root
  1. going back to the Task examples given in this issue and our use cases.

Looking at: https://taskfile.dev/usage/#vars-of-included-taskfiles and trying to modifing my examples above to implement suggestions from documentation (using Task v3.17.0):

root Taskfile content:

version: '3'

includes:
  imported:
    taskfile: ./imported/Taskfile.yml
    vars:
      custom_value: included-root

vars:
  custom_value: root

tasks:
  print_var:
    cmds:
      - echo {{.custom_value}}

imported Taskfile content

version: '3'

vars:
  custom_value: included

tasks:
  print_var:
    cmds:
      - echo {{.custom_value}}
(Example 1:) This is problematic because root Task file and all other includes would use the variable value 
from the first included Taskfile.
➜  (from root)task print_var         
task: [print_var] echo included # should be 'echo root'
included # should be root

(Example 2:)  This is fine. From the root the variable is overridden
➜  (from root) task imported:print_var
task: [imported:print_var] echo included-root
included-root

(Example 3:)  This is fine because it enables you to run your sub Taskfile independently with its own 
variables.
➜  cd imported           
➜  (from imported) task print_var 
task: [print_var] echo included
included

which in my opinion even further shows that this ticket is needed and that the behavior described in the issue should be a bug and not a wanted behavior.

Why?

  • we should be able to run each sub Taskfile independently with only this Taskfile ( see Example 3)
  • we should be able to run each sub Taskfile from the root Taskfile ( see Example 2) and override only the variables that we want
  • the root Taskfile (and other sub Taskfiles, if you import more than 1) should use the values of variables declared in root file and not the default value of a variable loaded from the first include.

Our use case is not much different than these simple examples with echo. We use Task to drive our terraform deployments working with multiple workspaces and modules. We noticed the issue because we had the same variable TERRAFORM_CMD= aws-vault exec ... -- terraform` declared in two different files and the root one was always inheriting the value from first (or last?; I don't remember well) included Taskfile and not the root one.

@Zebradil
Copy link

We're facing a similar issue.

The idea is to have a reusable Taskfile with a configurable version of a command line tool. In this example, a docker image tag is to be configured.

Taskfile.yaml includes Taskfile_docker.yaml and overrides the TAG variable with a bookworm value.
Taskfile_docker.yaml uses the TAG variable to build another variable — CMD, which represents the final command to run. If TAG is not provided, the latest value is taken by default.

Unfortunately, it seems like Taskfile evaluates global variables in the included file independently from any variables provided by the including file.

# Taskfile.yaml
version: '3'

includes:
  docker:
    taskfile: Taskfile_docker.yaml
    vars:
      TAG: bookworm
# Taskfile_docker.yaml
version: '3'

vars:
  TAG: '{{.TAG|default "latest"}}'
  CMD: 'docker run debian:{{.TAG}}'

tasks:
  test:
    cmds:
      - '{{.CMD}}} echo "{{.TAG}}"'
❯ task docker:test
task: [docker:test] docker run debian:latest echo "bookworm"
bookworm

Notice debian:latest in the output instead of the desired debian:bookworm.

A workaround for this issue is to use environment variables in the root Taskfile to override variables in included Taskfiles. But this doesn't allow to override of a variable with different values in different included Taskfiles.

# Taskfile.yaml
version: '3'

env:
  TAG: bookworm

includes:
  docker: Taskfile_docker.yaml

Taskfile_docker.yaml stays the same.

❯ task docker:test
task: [docker:test] docker run debian:bookworm echo "bookworm"
bookworm

Notice debian:bookworm in the output.

@vmaerten
Copy link
Member

As v3.36.0 with the recent changes of how to handle vars passed to included Taskfile (#1533).
Your first example works as expected

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

6 participants