Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 44 additions & 3 deletions docs/tasks/task-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ run = "cargo build"

### `depends`

- **Type**: `string | string[]`
- **Type**: `string | string[] | { task: string, args?: string[], env?: { [key]: string } }[]`

Tasks that must be run before this task. This is a list of task names or aliases. Arguments can be
passed to the task, e.g.: `depends = ["build --release"]`. If multiple tasks have the same dependency,
Expand All @@ -90,9 +90,46 @@ depends = ["build"]
run = "cargo test"
```

#### Passing environment variables to dependencies

You can pass environment variables to specific dependencies using two syntaxes:

**Shell-style inline:**

```mise-toml
[tasks.test]
depends = ["NODE_ENV=test setup"]
run = "npm test"

[tasks.setup]
run = 'echo "Setting up for $NODE_ENV"'
```

**Structured object format:**

```mise-toml
[tasks.test]
depends = [
{ task = "setup", env = { NODE_ENV = "test", DEBUG = "true" } }
]
run = "npm test"
```

The structured format also supports combining env vars with arguments:

```mise-toml
[tasks.deploy]
depends = [
{ task = "build", args = ["--release"], env = { RUSTFLAGS = "-C opt-level=3" } }
]
run = "./deploy.sh"
```

Note: These environment variables are passed only to the specified dependency, not to the current task or other dependencies.

### `depends_post`

- **Type**: `string | string[]`
- **Type**: `string | string[] | { task: string, args?: string[], env?: { [key]: string } }[]`

Like `depends` but these tasks run _after_ this task and its dependencies complete. For example, you
may want a `postlint` task that you can run individually without also running `lint`:
Expand All @@ -105,9 +142,11 @@ depends_post = ["postlint"]
run = "echo 'linting complete'"
```

Supports the same argument and environment variable syntax as `depends`.

### `wait_for`

- **Type**: `string | string[]`
- **Type**: `string | string[] | { task: string, args?: string[], env?: { [key]: string } }[]`

Similar to `depends`, it will wait for these tasks to complete before running however they won't be
added to the list of tasks to run. This is essentially optional dependencies.
Expand All @@ -118,6 +157,8 @@ wait_for = ["render"] # creates some js files, so if it's running, wait for it t
run = "eslint ."
```

Supports the same argument and environment variable syntax as `depends`.

### `env`

- **Type**: `{ [key]: string | int | bool }`
Expand Down
42 changes: 42 additions & 0 deletions e2e/tasks/test_task_dep_env
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash

# Test passing env vars to task dependencies

# Test shell-style env var syntax: "FOO=bar mytask"
cat <<EOF >mise.toml
[tasks.show-env]
run = 'echo "FOO=\$FOO BAZ=\$BAZ"'

[tasks.with-env-string]
depends = ["FOO=hello show-env"]
run = 'echo done'

[tasks.with-multiple-env]
depends = ["FOO=hello BAZ=world show-env"]
run = 'echo done'
EOF

assert_contains "mise run with-env-string" "FOO=hello"
assert_contains "mise run with-multiple-env" "FOO=hello BAZ=world"

# Test structured object syntax: { task = "mytask", env = { FOO = "bar" } }
cat <<EOF >mise.toml
[tasks.show-env]
run = 'echo "FOO=\$FOO BAZ=\$BAZ"'

[tasks.with-env-object]
depends = [{ task = "show-env", env = { FOO = "hello", BAZ = "world" } }]
run = 'echo done'

[tasks.with-env-and-args]
depends = [{ task = "echo-args", env = { FOO = "test" }, args = ["arg1", "arg2"] }]
run = 'echo done'

[tasks.echo-args]
run = 'echo "FOO=\$FOO" && echo'

Copilot AI Jan 17, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test verifies that FOO=test appears in output but doesn't validate that args arg1 and arg2 are actually passed to the echo-args task. The task's run command only echoes the FOO variable and doesn't incorporate the args, making line 42's assertion about args appearing in output unlikely to succeed as intended.

Copilot uses AI. Check for mistakes.
EOF

assert_contains "mise run with-env-object" "FOO=hello BAZ=world"
assert_contains "mise run with-env-and-args" "FOO=test"
# Args are appended to the command line, verify they appear in output
assert_contains "mise run with-env-and-args" "arg1 arg2"
21 changes: 21 additions & 0 deletions src/task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,15 @@ fn match_tasks_with_context(
.map(|t| {
let mut t = (*t).clone();
t.args = td.args.clone();
// Apply env vars from dependency
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated
if !td.env.is_empty() {
let env_directives: Vec<EnvDirective> = td
.env
.iter()
.map(|(k, v)| EnvDirective::Val(k.clone(), v.clone(), Default::default()))
.collect();
t = t.derive_env(&env_directives);
}
t
})
.collect_vec();
Expand Down Expand Up @@ -1407,10 +1416,12 @@ mod tests {
TaskDep {
task: "post1".to_string(),
args: vec![],
env: Default::default(),
},
TaskDep {
task: "post2".to_string(),
args: vec![],
env: Default::default(),
},
],
..Default::default()
Expand All @@ -1422,6 +1433,7 @@ mod tests {
depends_post: vec![TaskDep {
task: "other_post".to_string(),
args: vec![],
env: Default::default(),
}],
..Default::default()
};
Expand Down Expand Up @@ -1759,6 +1771,7 @@ echo "hello world"
depends: vec![crate::task::task_dep::TaskDep {
task: "task_b".to_string(),
args: vec![],
env: Default::default(),
}],
..Default::default()
};
Expand All @@ -1768,6 +1781,7 @@ echo "hello world"
depends: vec![crate::task::task_dep::TaskDep {
task: "task_a".to_string(),
args: vec![],
env: Default::default(),
}],
..Default::default()
};
Expand Down Expand Up @@ -1795,6 +1809,7 @@ echo "hello world"
depends: vec![crate::task::task_dep::TaskDep {
task: "task_b".to_string(),
args: vec![],
env: Default::default(),
}],
..Default::default()
};
Expand All @@ -1804,6 +1819,7 @@ echo "hello world"
depends: vec![crate::task::task_dep::TaskDep {
task: "task_c".to_string(),
args: vec![],
env: Default::default(),
}],
..Default::default()
};
Expand All @@ -1813,6 +1829,7 @@ echo "hello world"
depends: vec![crate::task::task_dep::TaskDep {
task: "task_a".to_string(),
args: vec![],
env: Default::default(),
}],
..Default::default()
};
Expand Down Expand Up @@ -1842,10 +1859,12 @@ echo "hello world"
crate::task::task_dep::TaskDep {
task: "task_a".to_string(),
args: vec![],
env: Default::default(),
},
crate::task::task_dep::TaskDep {
task: "task_b".to_string(),
args: vec![],
env: Default::default(),
},
],
..Default::default()
Expand All @@ -1856,6 +1875,7 @@ echo "hello world"
depends: vec![crate::task::task_dep::TaskDep {
task: "common".to_string(),
args: vec![],
env: Default::default(),
}],
..Default::default()
};
Expand All @@ -1865,6 +1885,7 @@ echo "hello world"
depends: vec![crate::task::task_dep::TaskDep {
task: "common".to_string(),
args: vec![],
env: Default::default(),
}],
..Default::default()
};
Expand Down
Loading
Loading