task icon indicating copy to clipboard operation
task copied to clipboard

Environment variable are loaded by dotenv before dependency tasks are executed

Open gsantoro opened this issue 2 years ago • 3 comments

Hello devs and thanks again for this great tool.

Today I have experienced a weird issue that I would like to verify with someone else here.

I would like to execute a task called test-pipeline that has a dependency task env-variables that creates an .env file at the location pointed by the variable .ENV_FILE.

  test-pipeline:
    deps:
      - env-variables  # create .ENV_FILE
    dotenv: 
      - "{{.ENV_FILE}}"
    cmds: 
      - <my BASH code thats needs env variables from {{.ENV_FILE}}>

I am expecting that if the .env file doesn't exists yet, it will be created by the task env-variables and then used by the task test-pipeline.

In reality this works as expected only if the .env file already exists. In order to make it works I need to run the following code instead.

  test-pipeline:
    deps:
      - env-variables # create .ENV_FILE
    cmds: 
      - |
        dotenv -f {{.ENV_FILE}} run -- bash -c \
          '<my BASH code thats needs env variables from {{.ENV_FILE}}>'

As you can see I need to use the binary dotenv from python-dotenv instead of the dotenv from Taskfile

Am I doing something wrong?

  • TTask version: v3.20.0
  • Operating System: Mac Os with M1 chip

gsantoro avatar Feb 10 '23 19:02 gsantoro

I did an investigation on this out of curiosity.

Envs from Dotenv file are loaded by read.Dotenv() - link read.Dotenv() is used by task.Executor.readDotEnvFiles() - link task.Executor.readDotEnvFiles() is used in task.Executor.Setup() - link

task dependencies are executed in task.Executor.RunTask() - link task.Executor.RunTask() is run by task.Executor.Run() - link

task.Executor.Setup() is run in the main task command on line 178 (link) before task.Executor.Run(), run on line 226 (link).

This suggests that Dotenv file is loaded during setup, before task dependencies are executed, so the use case is not supported.

A quick workaround is to manually run the dependency task instead of using Task deps.

From the code and PR that introduced this feature is not clear to me if is expected for dependency tasks to share the environment of the task they are a dependency of or if this behaviour emerged from the implementation. If is not expected I think would be less surprising to run the dependency tasks outside of the environment of the task they are a dependency of (they could in any case load their environment, which could be equal/overlap but in an explicit way).

If any maintainer would like to chime in here to provide their insights would be great.

endorama avatar Feb 13 '23 11:02 endorama

Also running into this issue. Would be nice to be able to re-eval dotenv after deps have ran.

bartvdbraak avatar Aug 31 '24 08:08 bartvdbraak

Example usage:

version: '3'

tasks:
  decrypt:
    desc: Decrypt files using sops.
    deps:
      - azure-login
    sources:
      - .env.enc
    cmds:
      - sops -d --input-type dotenv --output-type dotenv .env.enc > .env
    generates:
      - .env

  cloudflare:
    desc: Deploy the Cloudflare stack using OpenTofu.
    deps:
      - decrypt
    dir: cloudflare
    cmds:
      - tofu init
      - tofu apply

Now if I run task cloudflare, it will create the .env files by running decrypt as part of deps, however, I have no way of re-evaluating the variables from that file using dotenv it seems.

bartvdbraak avatar Sep 01 '24 19:09 bartvdbraak