Taskfile
Go-based YAML task runner. Variables, dependencies, incremental builds, and cross-platform task definitions.
Fundamentals
Basic Taskfile — YAML-based task runner
# Taskfile.yml
version: '3'
tasks:
build:
desc: Build the project
cmds:
- go build -o bin/app ./cmd/app
test:
desc: Run tests
cmds:
- go test ./...
clean:
desc: Remove build artifacts
cmds:
- rm -rf bin/
Run a task
task build
task test
task clean
# List available tasks
task --list
Taskfile is a Go-based alternative to Make. YAML syntax, cross-platform, no tab-sensitivity issues.
Variables and Environment
Variables — defined in Taskfile or from CLI
version: '3'
vars:
APP_NAME: myapp
VERSION:
sh: git describe --tags --always
env:
CGO_ENABLED: '0'
tasks:
build:
desc: Build {{.APP_NAME}} {{.VERSION}}
cmds:
- go build -ldflags "-X main.version={{.VERSION}}" -o bin/{{.APP_NAME}}
Override from CLI
task build APP_NAME=custom-name
Dependencies and Ordering
Task dependencies — run prerequisites first
tasks:
build:
deps: [lint, test]
cmds:
- go build -o bin/app
lint:
cmds:
- golangci-lint run
test:
cmds:
- go test ./...
Dependencies run in parallel by default. The build task waits for both lint and test to finish.
Sequential dependencies — when order matters
tasks:
deploy:
cmds:
- task: build
- task: push
- task: notify
Using task: in cmds runs them sequentially (build, then push, then notify).
Sources and Generates
Incremental builds — skip if nothing changed
tasks:
build:
sources:
- src/**/*.go
- go.mod
- go.sum
generates:
- bin/app
cmds:
- go build -o bin/app ./cmd/app
If none of the sources are newer than the generates, the task is skipped. Same concept as Make’s dependency graph.
Preconditions and Platforms
Preconditions — fail fast with a clear message
tasks:
deploy:
preconditions:
- sh: command -v kubectl
msg: "kubectl is required"
- sh: "[ -f kubeconfig.yml ]"
msg: "kubeconfig.yml not found"
cmds:
- kubectl apply -f manifests/
Platform-specific tasks
tasks:
install:
platforms: [linux]
cmds:
- sudo pacman -S {{.PACKAGE}}
install:
platforms: [darwin]
cmds:
- brew install {{.PACKAGE}}
Includes
Split large Taskfiles — include from subdirectories
# Taskfile.yml
version: '3'
includes:
docker: ./taskfiles/Docker.yml
docs: ./taskfiles/Docs.yml
task docker:build
task docs:serve
Taskfile vs Makefile
When to choose which
Use Makefile when:
- Project already uses Make
- You need file-based dependency graphs
- POSIX portability matters
- The team knows Make
Use Taskfile when:
- You want YAML over Makefile syntax
- Cross-platform without MSYS/WSL
- You want built-in variable templating
- Go project (Taskfile is the Go ecosystem standard)
Installation
Install Taskfile
# Arch Linux
sudo pacman -S go-task
# macOS
brew install go-task
# From script
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin