Taskfiles
Repository Structure
Taskfile.yaml # Root: includes namespaced taskfiles
.taskfiles/
├── inventory/taskfile.yaml # inv: IPMI host management
├── terragrunt/taskfile.yaml # tg: Infrastructure operations
├── worktree/taskfile.yaml # wt: Git worktree management
└── renovate/taskfile.yaml # renovate: Config validation
File Template
Always include schema and version:
---
# yaml-language-server: $schema=https://taskfile.dev/schema.json
version: "3"
vars:
MY_DIR: "{{.ROOT_DIR}}/path"
tasks:
my-task:
desc: Short description for --list output.
cmds:
- echo "hello"
Patterns
Include New Taskfiles
Add to root Taskfile.yaml:
includes:
namespace: .taskfiles/namespace
Wildcard Tasks
Use for parameterized operations:
plan-*:
desc: Plans a specific terragrunt stack.
vars:
STACK: "{{index .MATCH 0}}"
label: plan-{{.STACK}}
cmds:
- terragrunt plan --working-dir {{.INFRASTRUCTURE_DIR}}/stacks/{{.STACK}}
preconditions:
- which terragrunt
- test -d "{{.INFRASTRUCTURE_DIR}}/stacks/{{.STACK}}"
Dependencies
Run deps in parallel before cmds:
apply-*:
deps: [use, fmt]
cmds:
- terragrunt apply ...
Internal Helper Tasks
ipmi-command:
internal: true
silent: true
requires:
vars: [HOST, COMMAND]
cmds:
- ipmitool ... {{.COMMAND}}
Preconditions
preconditions:
- which required-tool
- test -d "{{.PATH}}"
- sh: test "{{.VALUE}}" != ""
msg: "VALUE cannot be empty"
Source Tracking
fmt:
sources:
- "{{.DIR}}/**/*.tf"
generates:
- "{{.DIR}}/**/*.tf"
cmds:
- tofu fmt -recursive
Dynamic Variables and For Loops
vars:
VALID_HOSTS:
sh: "cat {{.INVENTORY_FILE}} | yq -r '.hosts | keys[]'"
power-status:
cmds:
- for: { var: VALID_HOSTS }
cmd: task inv:status-{{.ITEM}}
CLI Arguments
new:
requires:
vars: [CLI_ARGS]
vars:
NAME: "{{.CLI_ARGS}}"
cmds:
- git worktree add ... -b "{{.NAME}}"
Usage: task wt:new -- feature-branch
References