Document the new experiment with:
- Environment namespace ({{.env.XXX}}) explanation
- Variable scoping between includes
- CLI variables priority
- Migration guide from legacy mode
- Comparison table between legacy and scoped modes
5.2 KiB
title, description, outline
| title | description | outline |
|---|---|---|
| Scoped Taskfiles | Experiment for variable isolation and env namespace in included Taskfiles | deep |
Scoped Taskfiles
::: warning
All experimental features are subject to breaking changes and/or removal at any time. We strongly recommend that you do not use these features in a production environment. They are intended for testing and feedback only.
:::
::: danger
This experiment breaks the following functionality:
- Environment variables are no longer available at root level in templates
- Before:
{{.PATH}},{{.MY_ENV}} - After:
{{.env.PATH}},{{.env.MY_ENV}}
- Before:
- Variables from sibling includes are no longer visible
- Include A cannot access variables defined in Include B
- Each include only sees: root vars + its own vars + parent vars
:::
::: info
To enable this experiment, set the environment variable:
TASK_X_SCOPED_TASKFILES=1. Check out
our guide to enabling experiments for more
information.
:::
This experiment introduces two major changes to how variables work in Task:
- Environment namespace: Environment variables (both OS and Taskfile
env:sections) are moved to a dedicated{{.env.XXX}}namespace, separating them from regular variables - Variable scoping: Variables defined in included Taskfiles are isolated - sibling includes cannot see each other's variables
Environment Namespace
With this experiment enabled, environment variables are no longer mixed with
regular variables at the template root level. Instead, they are accessible
through the {{.env.XXX}} namespace.
Comparison Table
| Template | Legacy | SCOPED_TASKFILES |
|---|---|---|
{{.MY_VAR}} (from vars:) |
Works | Works |
{{.MY_ENV}} (from env:) |
Works | <no value> |
{{.env.MY_ENV}} |
- | Works |
{{.PATH}} (OS) |
Works | <no value> |
{{.env.PATH}} (OS) |
- | Works |
{{.TASK}} (special) |
Works | Works (stays at root) |
Example
version: '3'
env:
DB_HOST: localhost
vars:
DB_NAME: mydb
tasks:
show:
cmds:
# Access Taskfile env: section
- echo "Host: {{.env.DB_HOST}}"
# Access regular vars (unchanged)
- echo "Name: {{.DB_NAME}}"
# Access OS environment variables
- echo "Path: {{.env.PATH}}"
# Special variables stay at root level
- echo "Task: {{.TASK}}"
Variable Scoping
Variables defined in included Taskfiles are now isolated from each other. Sibling includes cannot access each other's variables, but child includes can still inherit variables from their parent.
Example
# Taskfile.yml
version: '3'
vars:
ROOT_VAR: from_root
includes:
api: ./api
web: ./web
# api/Taskfile.yml
version: '3'
vars:
API_VAR: from_api
tasks:
show:
cmds:
# Inherited from root - works
- echo "ROOT_VAR={{.ROOT_VAR}}"
# Own variable - works
- echo "API_VAR={{.API_VAR}}"
# From sibling include - NOT visible
- echo "WEB_VAR={{.WEB_VAR}}"
# web/Taskfile.yml
version: '3'
vars:
WEB_VAR: from_web
tasks:
show:
cmds:
# Inherited from root - works
- echo "ROOT_VAR={{.ROOT_VAR}}"
# Own variable - works
- echo "WEB_VAR={{.WEB_VAR}}"
# From sibling include - NOT visible
- echo "API_VAR={{.API_VAR}}"
CLI Variables Priority
With this experiment, CLI variables (passed as task foo VAR=value) have the
highest priority and will override task-level variables.
version: '3'
tasks:
greet:
vars:
NAME: from_task
cmds:
- echo "Hello {{.NAME}}"
# CLI vars now override task vars
TASK_X_SCOPED_TASKFILES=1 task greet NAME=cli
# Output: Hello cli
Migration Guide
To migrate your Taskfiles to use this experiment:
-
Update environment variable references in your templates:
{{.PATH}}becomes{{.env.PATH}}{{.HOME}}becomes{{.env.HOME}}{{.MY_TASKFILE_ENV}}becomes{{.env.MY_TASKFILE_ENV}}
-
Variables in
vars:sections remain unchanged:{{.MY_VAR}}still works the same way
-
Special variables stay at root level:
{{.TASK}},{{.ROOT_DIR}},{{.TASKFILE}},{{.TASKFILE_DIR}}, etc.
-
Review cross-include variable dependencies:
- If your included Taskfiles rely on variables from sibling includes, you'll
need to either move those variables to the root Taskfile or pass them
explicitly via the
vars:attribute in theincludes:section.
- If your included Taskfiles rely on variables from sibling includes, you'll
need to either move those variables to the root Taskfile or pass them
explicitly via the