You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Precedence of environment variables not respected in v3.20.0 #993
I suspect that this is related to the newly merge task level dotenv support.
What I am seeing that environment variables specified explicitly at the task level no longer take precedence over ones defined by dotenv. For example, given a Taskfile of the form:
# dotenv file exports a `DATABASE_NAME` env var
dotenv: ['.env', '{{.HOME}}/.adapt.env']
task generate:config:
env:
DATABASE_NAME: "whatever"
cmds:
- echo "${DATABASE_NAME}"
You will always get the value of DATABASE_NAME defined by dotenv rather than the override defined at the local task level
I have a task that generates a dotenv configuration file at .env from a .env.tmpl file. From time to time, new configuration keys are added to the template and configuration needs to be regenerated. This task is called generate:config and looks something like this:
generate:config:
desc: Generate a config file
method: none
preconditions:
- sh: "! test -f .env"
msg: "Existing config file found at `.env`, halting..."
sources:
- .env.tmpl
generates:
- .env
vars:
# Replace slashes with underscores to create URL safe branch identifier
GIT_BRANCH_SAFE:
sh: git branch --show-current | tr / _
env:
TZ: UTC
DATABASE_NAME: { { .GIT_BRANCH_SAFE } }
DATABASE_USER: { { .GIT_BRANCH_SAFE } }
DATABASE_HOST: localhost
DATABASE_PORT: 5432
NODE_ENV: development
WEBAPP_PORT: 5001
API_BASE_URL: http://localhost:3000
cmds:
- cmd: envsubst < .env.tmpl > .env
silent: true
- cmd: echo "Wrote new configuration to $PWD/.env:"
silent: true
- task: config
I have another task called reinit that destroys the .env file (among other things) and then calls down to generate:config to build a new configuration from the template.
What I am seeing that the values that wind up being written out to the file are the ones from the previously deleted .env file rather than the explicit overrides specified in the generate:config task (or dynamically retrieved/generated values from parts of the example task ommitted for brevity.
In previous versions of Task, this all worked perfectly. Now I can only get the tasks to run by using an env -i execution to clean the environment like so:
generate:worktree-from-remote:
desc: Generate a new worktree tracking a remote branch
aliases: ['gwt']
preconditions:
- sh: "[ '{{.BRANCH}}' != '<no value>' ]"
msg: "Error: BRANCH not set.\nUsage: task generate:worktree-from-remote BRANCH=<WORKTREE_NAME>"
dir: '{{.ADAPT_WORKTREES_DIR}}'
cmds:
- cd main && git pull origin main
- git fetch origin
- git worktree add --track -B {{.BRANCH}} {{.BRANCH}} origin/{{.BRANCH}}
# NOTE: workaround for Task v3.20.0 regression (see https://github.com/go-task/task/issues/993)
# - task --dir {{.BRANCH}} init
- env -i USER="$USER" HOME="$HOME" PATH="$PATH" bash -l -c "source $(brew --prefix nvm)/nvm.sh && task --dir {{.BRANCH}} init"
Once the values from the previous .env are loaded by Task no overrides or local references instructing it to load from .env work -- it's like the environment is being hopelessly polluted
Indeed. The documentation explicitly informs that the expected behavior should be the opposite of what we get in the, as of now latest, v3.24.0 release and main branch. Like @zbindenren demonstrated in their comment, the observed output generated by the current implementation is that the predefined environment where Task is invoked is getting a greater precedence than any defined content of an env: section in any hierarchy position of a Taskfile.yml file. Doesn't matter if the definition is inside a task: or in the file root.
I believe there's no "correct" way of defining this order, there are arguments and uses for both ways, but the documentation should reflect the actual behavior. What was the original intent? Should we fix the code or the docs?
@bcdonadio That documentation for Task variables (vars:), and not environment variables (env:) inside Task. The behavior differs slightly (which I agree may be confusing).
See discussion at #1038 (comment). Change that would be a breaking change, but maybe a setting would be nice to make all users happy (some people like the current behavior).
@andreynering Yeah, I believe you're right. This line further reinforces the idea that they all follow the same rules, but doesn't specifically states that they behave the same in every possible case.
I think it would be a good idea just to make this behavior clear in the docs of this major release (with a mere patch bump), and only after that discuss and ponder whether should that be implemented as a breaking change in the next major, if there should be a config statement to change the default behavior in the next minor or whatever the solution might ultimately be.
Just trying to follow the principle of least surprise.
I want to override JAVA_HOME env var defined by the OS because I am managing my own Java installation which should be used instead of OS-wide. I am unable to set the global env override in Taskfile but I want to :(
as a workaround, I am forced to override env var right before executing the Maven, for example:
Should just ignore the variable values explicitly provided via the vars stanza and defer to the environment?
How is this even a discussion or a potentially breaking change? It is clearly incorrect. I am telling the task explicitly what I want the value to be and it is just ignoring it. It's a straight up bug and invalid behavior. Who in the universe is going to have their code broken by providing an explicit input value that is magically ignored based on the environment?
Hi all, there are many open issues related to variables in v3. To help centralise and focus our discussions we have created a new megathread. The env precedence experiment is now stable and there are open tickets linked from the megathread to discuss inheritance and scoping so I'm going to close this issue.
Activity
andreynering commentedon Jan 29, 2023
Hi @blakewatters,
I could not reproduce this issue.
I tried with global
dotenvand also localdotenvand in both scenarios it's working as expected: the local env in considered.blakewatters commentedon Feb 1, 2023
Okay let me try being a little more specific:
I have a task that generates a
dotenvconfiguration file at.envfrom a.env.tmplfile. From time to time, new configuration keys are added to the template and configuration needs to be regenerated. This task is calledgenerate:configand looks something like this:I have another task called
reinitthat destroys the.envfile (among other things) and then calls down togenerate:configto build a new configuration from the template.What I am seeing that the values that wind up being written out to the file are the ones from the previously deleted
.envfile rather than the explicit overrides specified in thegenerate:configtask (or dynamically retrieved/generated values from parts of the example task ommitted for brevity.In previous versions of Task, this all worked perfectly. Now I can only get the tasks to run by using an
env -iexecution to clean the environment like so:Once the values from the previous
.envare loaded by Task no overrides or local references instructing it to load from.envwork -- it's like the environment is being hopelessly pollutedzbindenren commentedon Apr 27, 2023
I have a similar problem if a variable is already defined in the shell.
For the taskfile:
everything works as expected:
But when I do the following:
In my opinion it should print
overridenotfoo. This leads to hard to debug issues in task files.bcdonadio commentedon May 12, 2023
Indeed. The documentation explicitly informs that the expected behavior should be the opposite of what we get in the, as of now latest, v3.24.0 release and main branch. Like @zbindenren demonstrated in their comment, the observed output generated by the current implementation is that the predefined environment where Task is invoked is getting a greater precedence than any defined content of an
env:section in any hierarchy position of aTaskfile.ymlfile. Doesn't matter if the definition is inside atask:or in the file root.I believe there's no "correct" way of defining this order, there are arguments and uses for both ways, but the documentation should reflect the actual behavior. What was the original intent? Should we fix the code or the docs?
andreynering commentedon May 23, 2023
@bcdonadio That documentation for Task variables (
vars:), and not environment variables (env:) inside Task. The behavior differs slightly (which I agree may be confusing).See discussion at #1038 (comment). Change that would be a breaking change, but maybe a setting would be nice to make all users happy (some people like the current behavior).
bcdonadio commentedon May 23, 2023
@andreynering Yeah, I believe you're right. This line further reinforces the idea that they all follow the same rules, but doesn't specifically states that they behave the same in every possible case.
I think it would be a good idea just to make this behavior clear in the docs of this major release (with a mere patch bump), and only after that discuss and ponder whether should that be implemented as a breaking change in the next major, if there should be a config statement to change the default behavior in the next minor or whatever the solution might ultimately be.
Just trying to follow the principle of least surprise.
krystian-panek-vmltech commentedon Aug 14, 2023
I have the same problem...
I want to override
JAVA_HOMEenv var defined by the OS because I am managing my own Java installation which should be used instead of OS-wide. I am unable to set the global env override in Taskfile but I want to :(as a workaround, I am forced to override env var right before executing the Maven, for example:
setting
env: JAVA_HOME: '{{ .AEM_BUILD_JAVA_HOME }}'anywhere (global or task level) is not effective; maybe some new section like
env_overridewill do the trick? :)or sth like:
blakewatters commentedon Dec 7, 2024
lol I find this entire discussion pretty amusing. We are 18 months deep and there is apparently some disagreement about whether or not a task such as:
Should just ignore the variable values explicitly provided via the vars stanza and defer to the environment?
How is this even a discussion or a potentially breaking change? It is clearly incorrect. I am telling the task explicitly what I want the value to be and it is just ignoring it. It's a straight up bug and invalid behavior. Who in the universe is going to have their code broken by providing an explicit input value that is magically ignored based on the environment?
pd93 commentedon Feb 3, 2025
Hi all, there are many open issues related to variables in v3. To help centralise and focus our discussions we have created a new megathread. The env precedence experiment is now stable and there are open tickets linked from the megathread to discuss inheritance and scoping so I'm going to close this issue.