MEMO-049: Task Build System Migration
Overview
Migration from GNU Make to Task completed in October 2024. This memo documents the rationale, migration process, and provides guidance for developers transitioning from Make to Task.
Status
Completed: October 2024
Migration File: Originally TASK_MIGRATION.md (archived to this memo)
Current Build System: Task (Taskfile.yml)
Legacy Build System: Make (Makefile.legacy, no longer maintained)
Why Task?
Problems with Make
- Manual dependency tracking: Make requires explicitly listing source files, which is error-prone
- Slow with binary targets: Make checks timestamps, but rebuilds are slow or skipped incorrectly
- Complex glob patterns: Using
findin Make is awkward and evaluated at parse-time - Poor multi-language support: Make was designed for C, not Go/Rust/Python polyglots
Benefits of Task
- Automatic change detection: Uses checksum-based detection via
sourcesandgenerates - Parallel by default: Tasks run concurrently when possible
- Cleaner syntax: YAML instead of Make's arcane syntax
- Multi-language friendly: Designed for modern polyglot projects
- Built-in file watching: No need for external tools
- Cross-platform: Works identically on macOS, Linux, and Windows
Installation
macOS (Homebrew)
brew install go-task
Linux/macOS (install script)
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d
Alternative: Go install
go install github.com/go-task/task/v3/cmd/task@latest
Verify installation
task --version
Command Mapping
All make commands have been converted to task commands:
| Make Command | Task Command | Notes |
|---|---|---|
make | task | Default target (build all) |
make help | task --list | Show available tasks |
make build | task build | Build all components |
make proxy | task proxy | Build Rust proxy |
make prismctl | task prismctl | Build prismctl |
make test | task test | Run all tests |
make test-parallel | task test-parallel | Run tests in parallel |
make lint | task lint | Lint all code |
make lint-parallel | task lint-parallel | Lint in parallel |
make fmt | task fmt | Format all code |
make clean | task clean | Clean build artifacts |
make proto | task proto | Generate protobuf |
make coverage | task coverage | Generate coverage |
make docs | task docs | Build documentation |
make ci | task ci | Run CI pipeline |
Key Differences
1. Automatic Dependency Tracking
Make (manual):
$(BINARIES_DIR)/prismctl: cmd/prismctl/go.mod
cd cmd/prismctl && go build -o $(BINARIES_DIR)/prismctl .
Task (automatic):
prismctl:
desc: Build prismctl CLI tool
sources:
- cmd/prismctl/**/*.go
- cmd/prismctl/go.mod
- cmd/prismctl/go.sum
generates:
- '{{.BINARIES_DIR}}/prismctl'
cmds:
- cd cmd/prismctl && go build -o {{.BINARIES_DIR}}/prismctl .
Task automatically:
- Checksums all source files
- Only rebuilds if sources changed
- No manual glob patterns needed
2. Parallel Execution
Make: Sequential by default, use make -j4 for parallelism
Task: Parallel by default when using deps:
build:
desc: Build all components
deps: [proxy, build-cmds, patterns] # Runs in parallel!
3. Variables
Make: Environment variables and shell expansion Task: Built-in variable system with templates
vars:
BUILD_DIR: '{{.ROOT_DIR}}/build'
BINARIES_DIR: '{{.BUILD_DIR}}/binaries'
tasks:
proxy:
cmds:
- cp target/release/prism-proxy {{.BINARIES_DIR}}/
4. No More .PHONY
Task doesn't use file targets by default, so no need for .PHONY declarations.
Quick Start
-
Install Task (see Installation above)
-
List available tasks:
task --list -
Run default build:
task -
Run specific task:
task prismctl -
Run with variables:
task test-acceptance-parallel-backends BACKENDS=MemStore,Redis -
Watch and rebuild (built-in):
task --watch proxy
Advanced Features
Incremental Builds
Task only rebuilds when sources change:
$ task proxy
task: Task "proxy" is up to date
$ touch prism-proxy/src/main.rs
$ task proxy
Building Rust proxy...
✓ Proxy built
Parallel Testing
# Run all tests in parallel (automatic with deps)
task test-parallel
# Explicit parallel execution
task --parallel lint-rust lint-python lint-go
Dry Run
# See what would run without executing
task --dry proxy
Summary View
# Show task descriptions
task --list-all
CI/CD Integration
GitHub Actions workflows have been updated to install and use Task:
- name: Install Task
run: |
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
- name: Build
run: task build
Troubleshooting
Task not found after install
# Ensure Task is in your PATH
export PATH="$HOME/.local/bin:$PATH"
# Or use full path
~/.local/bin/task --list
Task always rebuilds
- Check that
sourcesandgeneratesare correctly specified - Use
task --status <taskname>to debug - Ensure generated files match exactly
Need old Makefile?
The original Makefile has been archived as Makefile.legacy for reference.
Resources
Feedback
If you encounter issues with the Task migration, please:
- Check this migration guide
- Review the Taskfile.yml
- Open an issue with details about the problem
Legacy Support
The original Makefile has been preserved as Makefile.legacy for reference but is no longer maintained. All development should use Task going forward.
Impact
Developer Experience: Improved build times with automatic dependency detection and parallel execution CI/CD: Simplified workflows with consistent cross-platform behavior Maintenance: Easier to understand and modify YAML syntax vs Make's syntax