Basics
# Run default task
task
# Run named task
task build
# Run multiple tasks
task lint test
# List available tasks
task --list
task -l
# Dry run (show commands)
task build --dry
# Force run (ignore up-to-date checks)
task build --force
Taskfile Structure
# Taskfile.yml
version: '3'
vars:
APP_NAME: myapp
BUILD_DIR: bin
tasks:
default:
cmds:
- task: test
- task: build
build:
desc: Build the application
cmds:
- go build -o {{.BUILD_DIR}}/{{.APP_NAME}} ./cmd/api
test:
desc: Run tests
cmds:
- go test ./...
Variables
# Global variables
vars:
ENV: dev
PORT: 8080
# Dynamic variables (shell output)
vars:
GIT_SHA:
sh: git rev-parse --short HEAD
VERSION:
sh: cat VERSION
# Task-level variables
tasks:
deploy:
vars:
TARGET: '{{.ENV | default "staging"}}'
cmds:
- echo "Deploying to {{.TARGET}}"
# Environment variables
tasks:
run:
env:
PORT: '{{.PORT}}'
LOG_LEVEL: debug
cmds:
- go run ./cmd/api
Task Dependencies
tasks:
build:
deps: [generate, lint]
cmds:
- go build -o bin/server .
# Dependencies run in parallel by default.
# Use 'cmds' with 'task' to run sequentially.
deploy:
cmds:
- task: test
- task: build
- task: push
# Dependency with variables
docker:
deps:
- task: build
vars:
GOOS: linux
GOARCH: amd64
cmds:
- docker build -t myapp .
Sources and Generates (Up-to-date Checks)
tasks:
build:
desc: Build binary
sources:
- ./**/*.go
- go.mod
- go.sum
generates:
- bin/server
cmds:
- go build -o bin/server ./cmd/api
# Method: checksum (default) or timestamp
assets:
sources:
- src/assets/**/*
generates:
- dist/assets/**/*
method: timestamp
cmds:
- cp -r src/assets dist/
Conditionals and Status
tasks:
install:
desc: Install dependencies
status:
- test -d node_modules
cmds:
- npm install
migrate:
desc: Run migrations
preconditions:
- sh: test -f .env
msg: ".env file is required"
- sh: command -v migrate
msg: "migrate tool not installed"
cmds:
- migrate up
tasks:
open:
desc: Open the app
cmds:
- cmd: open http://localhost:8080
platforms: [darwin]
- cmd: xdg-open http://localhost:8080
platforms: [linux]
Internal Tasks and Aliases
tasks:
build:
aliases: [b]
desc: Build the app
cmds:
- go build .
# Internal tasks don't show in --list
generate-proto:
internal: true
cmds:
- protoc --go_out=. *.proto
Includes
# Taskfile.yml
version: '3'
includes:
docker: ./taskfiles/Docker.yml
db: ./taskfiles/Database.yml
# With directory override
api:
taskfile: ./api/Taskfile.yml
dir: ./api
# Run included tasks with namespace
task docker:build
task db:migrate
task api:test
Directory and Shell
tasks:
frontend:
dir: ./frontend
cmds:
- npm run build
# Run in specific shell
script:
cmds:
- cmd: |
set -euo pipefail
echo "strict mode"
shell: bash
Interactive and Silent
tasks:
deploy:
prompt: "Deploy to production?"
cmds:
- ./deploy.sh
quiet:
silent: true
cmds:
- echo "this won't echo the command itself"
# Ignore errors
cleanup:
cmds:
- cmd: rm -rf tmp/
ignore_error: true
- echo "done"
Dotenv
version: '3'
dotenv: ['.env', '.env.local']
tasks:
run:
cmds:
- echo $DATABASE_URL
Useful Patterns
version: '3'
vars:
APP: myapp
GIT_SHA:
sh: git rev-parse --short HEAD
tasks:
default:
cmds:
- task: lint
- task: test
- task: build
dev:
desc: Run with live reload
deps: [install]
cmds:
- air -c .air.toml
lint:
desc: Lint code
cmds:
- go vet ./...
- golangci-lint run
test:
desc: Run tests
cmds:
- go test -race -cover ./...
build:
desc: Build binary
sources: ['./**/*.go', 'go.mod']
generates: ['bin/{{.APP}}']
cmds:
- go build -ldflags "-X main.version={{.GIT_SHA}}" -o bin/{{.APP}} ./cmd/api
docker:
desc: Build Docker image
cmds:
- docker build -t {{.APP}}:{{.GIT_SHA}} .
clean:
desc: Remove build artifacts
cmds:
- rm -rf bin/ dist/ tmp/