| title | Taskfile Schema Reference |
|---|---|
| description | A reference for the Taskfile schema |
| outline | deep |
This page documents all available properties and types for the Taskfile schema version 3, based on the official JSON schema.
The root Taskfile schema defines the structure of your main Taskfile.yml.
- Type:
stringornumber - Required: Yes
- Valid values:
"3",3, or any valid semver string - Description: Version of the Taskfile schema
version: '3'- Type:
stringorobject - Default:
interleaved - Options:
interleaved,group,prefixed - Description: Controls how task output is displayed
# Simple string format
output: group
# Advanced object format
output:
group:
begin: "::group::{{.TASK}}"
end: "::endgroup::"
error_only: false- Type:
map[string]Include - Description: Include other Taskfiles
includes:
# Simple string format
docs: ./Taskfile.yml
# Full object format
backend:
taskfile: ./backend
dir: ./backend
optional: false
flatten: false
internal: false
aliases: [api]
excludes: [internal-task]
vars:
SERVICE_NAME: backend
checksum: abc123...- Type:
map[string]Variable - Description: Global variables available to all tasks
vars:
# Simple values
APP_NAME: myapp
VERSION: 1.0.0
DEBUG: true
PORT: 8080
FEATURES: [auth, logging]
# Dynamic variables
COMMIT_HASH:
sh: git rev-parse HEAD
# Variable references
BUILD_VERSION:
ref: .VERSION
# Map variables
CONFIG:
map:
database: postgres
cache: redis- Type:
map[string]Variable - Description: Global environment variables
env:
NODE_ENV: production
DATABASE_URL:
sh: echo $DATABASE_URL- Type:
map[string]Task - Description: Task definitions
tasks:
# Simple string format
hello: echo "Hello World"
# Array format
build:
- go mod tidy
- go build ./...
# Full object format
deploy:
desc: Deploy the application
cmds:
- ./scripts/deploy.sh- Type:
bool - Default:
false - Description: Suppress task name and command output by default
silent: true- Type:
[]string - Description: Load environment variables from .env files. When the same variable is defined in multiple files, the first file in the list takes precedence.
dotenv:
- .env.local # Highest priority
- .env # Lowest priority- Type:
string - Default:
always - Options:
always,once,when_changed - Description: Default execution behavior for tasks
run: once- Type:
string - Default:
100ms - Pattern:
^[0-9]+(?:m|s|ms)$ - Description: Watch interval for file changes
interval: 1s- Type:
[]string - Options:
allexport,a,errexit,e,noexec,n,noglob,f,nounset,u,xtrace,x,pipefail - Description: POSIX shell options for all commands
set: [errexit, nounset, pipefail]- Type:
[]string - Options:
expand_aliases,globstar,nullglob - Description: Bash shell options for all commands
shopt: [globstar]Configuration for including external Taskfiles.
- Type:
string - Required: Yes
- Description: Path to the Taskfile or directory to include
includes:
backend: ./backend/Taskfile.yml
# Shorthand for above
frontend: ./frontend- Type:
string - Description: Working directory for included tasks
includes:
api:
taskfile: ./api
dir: ./api- Type:
bool - Default:
false - Description: Don't error if the included file doesn't exist
includes:
optional-tasks:
taskfile: ./optional.yml
optional: true- Type:
bool - Default:
false - Description: Include tasks without namespace prefix
includes:
common:
taskfile: ./common.yml
flatten: true- Type:
bool - Default:
false - Description: Hide included tasks from command line and
--list
includes:
internal:
taskfile: ./internal.yml
internal: true- Type:
[]string - Description: Alternative names for the namespace
includes:
database:
taskfile: ./db.yml
aliases: [db, data]- Type:
[]string - Description: Tasks to exclude from inclusion
includes:
shared:
taskfile: ./shared.yml
excludes: [internal-setup, debug-only]- Type:
map[string]Variable - Description: Variables to pass to the included Taskfile
includes:
deploy:
taskfile: ./deploy.yml
vars:
ENVIRONMENT: productionVariables support multiple types and can be static values, dynamic commands, references, or maps.
vars:
# String
APP_NAME: myapp
# Number
PORT: 8080
# Boolean
DEBUG: true
# Array
FEATURES: [auth, logging, metrics]
# Null
OPTIONAL_VAR: nullvars:
COMMIT_HASH:
sh: git rev-parse HEAD
BUILD_TIME:
sh: date -u +"%Y-%m-%dT%H:%M:%SZ"vars:
BASE_VERSION: 1.0.0
FULL_VERSION:
ref: .BASE_VERSIONvars:
CONFIG:
map:
database:
host: localhost
port: 5432
cache:
type: redis
ttl: 3600Variables can reference previously defined variables:
vars:
GREETING: Hello
TARGET: World
MESSAGE: '{{.GREETING}} {{.TARGET}}!'Individual task configuration with multiple syntax options.
tasks:
# String command
hello: echo "Hello World"
# Array of commands
build:
- go mod tidy
- go build ./...
# Object with cmd shorthand
test:
cmd: go test ./...- Type:
[]Command - Description: Commands to execute
tasks:
build:
cmds:
- go build ./...
- echo "Build complete"- Type:
string - Description: Single command (alternative to
cmds)
tasks:
test:
cmd: go test ./...- Type:
[]Dependency - Description: Tasks to run before this task
tasks:
# Simple dependencies
deploy:
deps: [build, test]
cmds:
- ./deploy.sh
# Dependencies with variables
advanced-deploy:
deps:
- task: build
vars:
ENVIRONMENT: production
- task: test
vars:
COVERAGE: true
cmds:
- ./deploy.sh
# Silent dependencies
main:
deps:
- task: setup
silent: true
cmds:
- echo "Main task"
# Loop dependencies
test-all:
deps:
- for: [unit, integration, e2e]
task: test
vars:
TEST_TYPE: '{{.ITEM}}'
cmds:
- echo "All tests completed"- Type:
[]Dependency - Description: Tasks to run before fingerprinting and locking. Setup tasks run unconditionally every time the parent task is invoked — even when the parent is already up to date. They execute sequentially in the order listed.
Use setup for operations that must complete before the parent's source
fingerprint can be computed, such as code generation, version stamping, or
fetching external inputs. Setup task outputs are not merged into the
parent's fingerprint; use sources / generates with from: deps on the
parent if you need that.
tasks:
build:
setup:
- generate-version
sources:
- version.txt
- src/**/*.go
generates:
- bin/app
cmds:
- go build -o bin/app ./cmd
generate-version:
cmds:
- git describe --tags > version.txt- Type:
string - Description: Short description shown in
--list
tasks:
test:
desc: Run unit tests
cmds:
- go test ./...- Type:
string - Description: Detailed description shown in
--summary
tasks:
deploy:
desc: Deploy to production
summary: |
Deploy the application to production environment.
This includes building, testing, and uploading artifacts.- Type:
stringor[]string - Description: Prompts shown before task execution
tasks:
# Single prompt
deploy:
prompt: "Deploy to production?"
cmds:
- ./deploy.sh
# Multiple prompts
deploy-multi:
prompt:
- "Are you sure?"
- "This will affect live users!"
cmds:
- ./deploy.sh- Type:
[]string - Description: Alternative names for the task
tasks:
build:
aliases: [compile, make]
cmds:
- go build ./...- Type:
[]stringor[]Glob - Description: Source files to monitor for changes
tasks:
build:
sources:
- '**/*.go'
- go.mod
# With exclusions
- exclude: '**/*_test.go'
cmds:
- go build ./...- Type:
[]stringor[]Glob - Description: Files generated by this task
tasks:
build:
sources: ['**/*.go']
generates:
- './app'
- exclude: '*.debug'
cmds:
- go build -o app ./cmd- Type:
[]string - Description: Commands to check if task should run
tasks:
install-deps:
status:
- test -f node_modules/.installed
cmds:
- npm install
- touch node_modules/.installed- Type:
[]Precondition - Description: Conditions that must be met before running
tasks:
# Simple precondition (shorthand)
build:
preconditions:
- test -d ./src
cmds:
- go build ./...
# Preconditions with custom messages
deploy:
preconditions:
- sh: test -n "$API_KEY"
msg: 'API_KEY environment variable is required'
- sh: test -f ./app
msg: "Application binary not found. Run 'task build' first."
cmds:
- ./deploy.sh- Type:
string - Description: Shell command to conditionally execute the task. If the command exits with a non-zero code, the task is skipped (not failed).
tasks:
# Task only runs in CI environment
deploy:
if: '[ "$CI" = "true" ]'
cmds:
- ./deploy.sh
# Using Go template expressions
build-prod:
if: '{{eq .ENV "production"}}'
cmds:
- go build -ldflags="-s -w" ./...- Type:
string - Description: The directory in which this task should run
- Default: If the task is in the root Taskfile, the default
dirisROOT_DIR. For included Taskfiles, the defaultdiris the value specified in their respectiveincludes.*.dirfield (if any).
tasks:
current-dir:
dir: '{{.USER_WORKING_DIR}}'
cmd: pwd- Type:
Requires - Description: Required variables with optional enum validation
tasks:
# Simple requirements
deploy:
requires:
vars: [API_KEY, ENVIRONMENT]
cmds:
- ./deploy.sh
# Requirements with enum validation
advanced-deploy:
requires:
vars:
- API_KEY
- name: ENVIRONMENT
enum: [development, staging, production]
- name: LOG_LEVEL
enum: [debug, info, warn, error]
cmds:
- echo "Deploying to {{.ENVIRONMENT}} with log level {{.LOG_LEVEL}}"
- ./deploy.shSee Prompting for missing variables interactively for information on enabling interactive prompts for missing required variables.
- Type:
bool - Default:
false - Description: Automatically run task in watch mode
tasks:
dev:
watch: true
cmds:
- npm run dev- Type:
string | object - Description: Configures remote caching and distributed locking for a task.
When specified as a string, it references a named cache model defined in the
top-level
caches:map. When specified as an object, it can inherit from a model and override individual fields.
Cache fields:
| Field | Type | Description |
|---|---|---|
inherit |
string |
Name of a cache model to inherit from |
enabled |
bool |
Explicitly enable or disable the cache block |
vk |
string |
Template string resolving to a vk-registry repository; see below |
api_key |
string |
Template string resolving to a bearer token (a vk-registry API key) |
namespace |
string |
Template string prefixing the entries and locks under vk |
url |
string |
Template string resolving to the cache URL (file://, oci://) |
lock |
string |
Lock URL (file://, redis://, vk://, vks://); see below |
ttl |
string |
TTL for cached assets (e.g. 48h, 7d); default 48h |
vk-registry: vk: host[:port]/repo names one vk-registry repository that
serves both the cache and the build-once lock, and derives the two URLs below
from it — the entry oci://host/repo:<namespace>-<task>-<checksum> (made
tag-safe and length-capped) and the lock vks://host/repo/<namespace>. The
credential is api_key (a bearer token, minted by the registry), else
$TASK_VK_API_KEY (the lock also honours $TASK_VK_LOCK_TOKEN in between);
the trust anchor for a private certificate is
$TASK_CACHE_OCI_CA. namespace keeps entries built by different toolchains
apart (it has no effect without vk). A vk that renders empty — its CI
variable unset on a developer machine — disables the block; one that renders to
anything but host[:port]/repo is an error. vk cannot be combined with url
or lock. api_key also works with an explicit oci:// URL and vk:// lock,
where it outranks every other credential.
caches:
default:
vk: '{{.CI_VK_REGISTRY}}' # e.g. registry.example/task-cache
namespace: '{{.BUILDER_TAG}}'Supported url (storage) schemes:
file://<dir>— local archives.oci://[user:password@]host/repo:tag[?ca=<file>][&cas=<dir>][&plainhttp=1]— a chunk-deduplicated artifact on any OCI registry. Environment credentials are$TASK_VK_API_KEY(a bearer token, such as a vk-registry API key) or$TASK_CACHE_OCI_USER/$TASK_CACHE_OCI_PASSWORD(Basic), with the token taking precedence.$TASK_CACHE_OCI_CAand$TASK_CACHE_OCI_CAS_DIRprovide the other environment settings. Against a vk-registry server, Task also negotiates its transparent-zstd upload mode automatically.
Supported lock schemes:
file://<dir>— local lockfiles (single host only).redis://[user:pass@]host[:port]/<prefix>— RedisSET NX EXwith a heartbeat.vk://host[:port]/<prefix>(vks://host[:port]/<prefix>[?ca=<file>]for HTTPS) — the vk-registry HTTP lock API, so one vk-registry serves both theoci://cache and the lock without Redis. Credential precedence is the block'sapi_key, URL Basic,$TASK_VK_LOCK_TOKEN,$TASK_VK_API_KEY, then$TASK_CACHE_OCI_USER/$TASK_CACHE_OCI_PASSWORD, allowing one token or account to cover both APIs. Credentials travel in the clear overvk://on every acquire, renew and release; usevks://outside trusted networks. Avks://lock adds?ca=<file>, or$TASK_CACHE_OCI_CAwhen unset, to the system trust store.
All template fields (url, lock, vk, api_key, namespace, enabled,
lock_timeout) support standard Task variables plus {{.TASK}},
{{.CHECKSUM}}, and the urlsafe template function.
Each renders in the dialect of the file it was written in: a caches: model in
the file defining it, a task-level override in the task's own file.
If the remote lock (e.g. Redis) is unavailable, Task logs a warning and falls back to a local file lock so the task still runs.
Both sources and generates entries support a from: directive that
copies entries from related tasks. Supported values are deps (direct
dependencies) and cmds (cmd task-calls). This allows wrapper tasks to
participate in fingerprinting and caching without duplicating glob patterns:
# Define reusable cache models at the top level
caches:
default:
enabled: '{{ne .CACHE_URL ""}}'
url: '{{.CACHE_URL}}/cache:{{urlsafe .TASK}}-{{.CHECKSUM}}.zip'
lock: '{{.CACHE_URL}}/lock:{{urlsafe .TASK}}-{{.CHECKSUM}}'
tasks:
build:
cache: default
sources:
- src/**/*.go
generates:
- bin/app
cmds:
- go build -o bin/app ./cmd
# Wrapper task: inherits both sources and generates from its deps.
build-all:
cache: default
sources:
- from: deps
generates:
- from: deps
deps:
- build
# Task that delegates via cmds: inherits from cmd task-calls.
build-lang:
sources:
- from: cmds
generates:
- from: cmds
cmds:
- task: build- Type:
[]string - Description: Platforms where this task should run
tasks:
windows-build:
platforms: [windows]
cmds:
- go build -o app.exe ./cmd
unix-build:
platforms: [linux, darwin]
cmds:
- go build -o app ./cmdIndividual command configuration within a task.
tasks:
example:
cmds:
- echo "Simple command"
- ls -latasks:
example:
cmds:
- cmd: echo "Hello World"
silent: true
ignore_error: false
platforms: [linux, darwin]
set: [errexit]
shopt: [globstar]tasks:
example:
cmds:
- task: other-task
vars:
PARAM: value
silent: falsetasks:
with-cleanup:
cmds:
- echo "Starting work"
# Deferred command string
- defer: echo "Cleaning up"
# Deferred task reference
- defer:
task: cleanup-task
vars:
CLEANUP_MODE: fulltasks:
greet-all:
cmds:
- for: [alice, bob, charlie]
cmd: echo "Hello {{.ITEM}}"tasks:
process-files:
sources: ['*.txt']
cmds:
- for: sources
cmd: wc -l {{.ITEM}}
- for: generates
cmd: gzip {{.ITEM}}tasks:
process-items:
vars:
ITEMS: 'item1,item2,item3'
cmds:
- for:
var: ITEMS
split: ','
as: CURRENT
cmd: echo "Processing {{.CURRENT}}"tasks:
test-matrix:
cmds:
- for:
matrix:
OS: [linux, windows, darwin]
ARCH: [amd64, arm64]
cmd: echo "Testing {{.ITEM.OS}}/{{.ITEM.ARCH}}"tasks:
build-all:
deps:
- for: [frontend, backend, worker]
task: build
vars:
SERVICE: '{{.ITEM}}'Use if to conditionally execute a command. If the shell command exits with a
non-zero code, the command is skipped.
tasks:
build:
cmds:
# Only run in production
- cmd: echo "Optimizing for production"
if: '[ "$ENV" = "production" ]'
# Using Go templates
- cmd: echo "Feature enabled"
if: '{{eq .ENABLE_FEATURE "true"}}'
# Inside for loops (evaluated per iteration)
- for: [a, b, c]
cmd: echo "processing {{.ITEM}}"
if: '[ "{{.ITEM}}" != "b" ]'Available set options for POSIX shell features:
allexport/a- Export all variableserrexit/e- Exit on errornoexec/n- Read commands but don't executenoglob/f- Disable pathname expansionnounset/u- Error on undefined variablesxtrace/x- Print commands before executionpipefail- Pipe failures propagate
# Global level
set: [errexit, nounset, pipefail]
tasks:
debug:
# Task level
set: [xtrace]
cmds:
- cmd: echo "This will be traced"
# Command level
set: [noexec]Available shopt options for Bash features:
expand_aliases- Enable alias expansionglobstar- Enable**recursive globbingnullglob- Null glob expansion
# Global level
shopt: [globstar]
tasks:
find-files:
# Task level
shopt: [nullglob]
cmds:
- cmd: ls **/*.go
# Command level
shopt: [globstar]