Manage Taskfile composition and task execution for DataRobot templates.
For most users, working with Taskfiles is straightforward:
# Compose a unified Taskfile from components
dr task compose
# List available tasks
dr task list
# Execute tasks
dr task run devThe command automatically discovers Taskfiles in your template components and aggregates them into a unified configuration.
Note
First time? If you're new to the CLI, start with the Quick start for step-by-step setup instructions.
dr task [command] [flags]The task command group provides utilities for working with Taskfiles in DataRobot application templates. It includes subcommands for composing unified Taskfiles from multiple component Taskfiles and executing tasks.
- compose—compose a unified Taskfile from component Taskfiles.
- list—list available tasks.
- run—execute template tasks.
Generate a root Taskfile.yaml by discovering and aggregating Taskfiles from subdirectories.
dr task compose [flags]The compose command automatically discovers Taskfiles in component directories and generates a unified root Taskfile.yaml that includes all components and aggregates common tasks. This allows you to run tasks across multiple components from a single entry point.
Key features:
- Automatic discovery—finds Taskfiles up to 2 levels deep in subdirectories.
- Task aggregation—discovers common tasks (lint, install, dev, deploy) and creates top-level tasks that delegate to components.
- Template support—uses customizable Go templates for flexible Taskfile generation.
- Auto-discovery—automatically detects
.Taskfile.templatein the root directory. - Gitignore integration—adds generated Taskfile to
.gitignoreautomatically.
-t, --template string Path to custom Taskfile template
-h, --help Help for compose -v, --verbose Enable verbose output
--debug Enable debug outputTo use dr task compose, your directory must meet these requirements:
- Contains a .env file—indicates you're in a DataRobot template directory.
- Contains component Taskfiles—subdirectories with
Taskfile.yamlorTaskfile.ymlfiles. - No dotenv conflicts—component Taskfiles cannot have their own
dotenvdirectives.
Expected directory structure:
my-template/
├── .env # Required: template marker
├── .Taskfile.template # Optional: custom template
├── .taskfile-data.yaml # Optional: template configuration
├── Taskfile.yaml # Generated: unified taskfile
├── backend/
│ ├── Taskfile.yaml # Component tasks
│ └── src/
├── frontend/
│ ├── Taskfile.yaml # Component tasks
│ └── src/
└── infra/
├── Taskfile.yaml # Component tasks
└── terraform/
Generate a Taskfile using the default embedded template:
dr task composeOutput:
Generated file saved to: Taskfile.yaml
Added /Taskfile.yaml line to .gitignore
This creates a Taskfile.yaml with:
- Environment configuration
- Includes for all discovered components
- Aggregated tasks (lint, install, dev, deploy)
If .Taskfile.template exists in the root directory:
dr task composeOutput:
Using auto-discovered template: .Taskfile.template
Generated file saved to: Taskfile.yaml
The command automatically uses your custom template.
Specify a custom template explicitly:
dr task compose --template templates/custom.yamlThis uses your custom template for generation instead of the embedded default.
dr task compose --template .datarobot/taskfile.templateThe default generated Taskfile.yaml includes:
---
# https://taskfile.dev
version: '3'
env:
ENV: testing
dotenv: ['.env', '.env.{{.ENV}}']
includes:
backend:
taskfile: ./backend/Taskfile.yaml
dir: ./backend
frontend:
taskfile: ./frontend/Taskfile.yaml
dir: ./frontend
infra:
taskfile: ./infra/Taskfile.yaml
dir: ./infra
tasks:
default:
desc: "ℹ️ Show all available tasks (run `task --list-all` to see hidden tasks)"
cmds:
- task --list --sort none
silent: true
start:
desc: "💻 Prepare local development environment"
cmds:
- dr dotenv setup
- task: install
lint:
desc: "🧹 Run linters"
cmds:
- task: backend:lint
- task: frontend:lint
install:
desc: "🛠️ Install all dependencies"
cmds:
- task: backend:install
- task: frontend:install
- task: infra:install
test:
desc: "🧪 Run tests across all components"
cmds:
- task: backend:test
- task: frontend:test
dev:
desc: "🚀 Run all services together"
cmds:
- |
task backend:dev &
sleep 3
task frontend:dev &
sleep 8
echo "✅ All servers started!"
wait
deploy:
desc: "🚀 Deploy all services"
cmds:
- task: infra:deploy
- task: backend:deploy
deploy-dev:
desc: "🚀 Deploy all services to development"
cmds:
- task: infra:deploy-dev
- task: backend:deploy-devThe compose command discovers these common tasks in component Taskfiles:
- lint—code linting and formatting.
- install—dependency installation.
- test—running test suites.
- dev—development server startup.
- deploy—production deployment operations.
- deploy-dev—development deployment operations.
For each discovered task type, it creates a top-level task that delegates to all components that have that task.
Create a custom template to control the generated Taskfile structure.
Save as .Taskfile.template:
---
version: '3'
env:
ENV: production
dotenv: ['.env', '.env.{{.ENV}}']
includes:
{{- range .Includes }}
{{ .Name }}:
taskfile: {{ .Taskfile }}
dir: {{ .Dir }}
{{- end }}
tasks:
default:
desc: "Show available tasks"
cmds:
- task --list
{{- if .HasLint }}
lint:
desc: "Run linters"
cmds:
{{- range .LintComponents }}
- task: {{ . }}:lint
{{- end }}
{{- end }}
{{- if .HasInstall }}
install:
desc: "Install dependencies"
cmds:
{{- range .InstallComponents }}
- task: {{ . }}:install
{{- end }}
{{- end }}
{{- if .HasTest }}
test:
desc: "Run tests"
cmds:
{{- range .TestComponents }}
- task: {{ . }}:test
{{- end }}
{{- end }}
# Custom task
check:
desc: "Run all checks"
cmds:
- task: lint
- task: testTemplates have access to these variables:
Includes (array):
.Name—component name (e.g., "backend")..Taskfile—relative path to Taskfile (e.g., "./backend/Taskfile.yaml")..Dir—relative directory path (e.g., "./backend").
Task flags (boolean):
.HasLint—true if any component has a lint task..HasInstall—true if any component has an install task..HasTest—true if any component has a test task..HasDev—true if any component has a dev task..HasDeploy—true if any component has a deploy task..HasDeployDev—true if any component has a deploy-dev task.
Task components (arrays):
.LintComponents—component names with lint tasks..InstallComponents—component names with install tasks..TestComponents—component names with test tasks..DevComponents—component names with dev tasks..DeployComponents—component names with deploy tasks..DeployDevComponents—component names with deploy-dev tasks.
Development ports (array):
.DevPorts[].Name—service name..DevPorts[].Port—port number.
version: '3'
dotenv: ['.env']
includes:
{{- range .Includes }}
{{ .Name }}:
taskfile: {{ .Taskfile }}
dir: {{ .Dir }}
{{- end }}
tasks:
default:
cmds:
- task --listversion: '3'
dotenv: ['.env']
includes:
{{- range .Includes }}
{{ .Name }}:
taskfile: {{ .Taskfile }}
dir: {{ .Dir }}
{{- end }}
tasks:
{{- if .HasLint }}
lint:
desc: "Run all linters"
cmds:
{{- range .LintComponents }}
- task: {{ . }}:lint
{{- end }}
{{- end }}
{{- if .HasInstall }}
install:
desc: "Install all dependencies"
cmds:
{{- range .InstallComponents }}
- task: {{ . }}:install
{{- end }}
{{- end }}
{{- if .HasTest }}
test:
desc: "Run all tests"
cmds:
{{- range .TestComponents }}
- task: {{ . }}:test
{{- end }}
{{- end }}
{{- if .HasDev }}
dev:
desc: "Start all services"
cmds:
{{- range .DevComponents }}
- task: {{ . }}:dev
{{- end }}
{{- end }}
{{- if .HasDeploy }}
deploy:
desc: "Deploy to production"
cmds:
{{- range .DeployComponents }}
- task: {{ . }}:deploy
{{- end }}
{{- end }}
{{- if .HasDeployDev }}
deploy-dev:
desc: "Deploy to development"
cmds:
{{- range .DeployDevComponents }}
- task: {{ . }}:deploy-dev
{{- end }}
{{- end }}
ci:
desc: "Run CI pipeline"
cmds:
- task: lint
- task: test
- task: buildThe compose command automatically adds the generated Taskfile to .gitignore:
/Taskfile.yamlThis prevents committing the generated file to version control. Each developer generates their own version based on their local component structure.
If you want to commit the generated Taskfile, remove it from .gitignore.
You don't seem to be in a DataRobot Template directory.
This command requires a .env file to be present.
Solution: Navigate to a template directory or run dr templates setup.
no Taskfiles found in child directories
Solution: Add Taskfiles to component directories or adjust your directory structure.
Error: Cannot generate Taskfile because an existing Taskfile already has a dotenv directive.
existing Taskfile already has dotenv directive: backend/Taskfile.yaml
Solution: Remove dotenv directives from component Taskfiles. The root Taskfile handles environment loading.
Error: template file not found: /path/to/template.yaml
Solution: Check the template path and ensure the file exists.
Each component Taskfile should be self-contained:
# backend/Taskfile.yaml
version: '3'
tasks:
dev:
desc: Start backend server
cmds:
- python -m uvicorn src.app.main:app --reload
test:
desc: Run tests
cmds:
- pytest
lint:
desc: Run linters
cmds:
- ruff check .
- mypy .Use the same task names across components for automatic aggregation:
lint—linting.install—dependency installation.test—testing.dev—development server.build—building artifacts.deploy—production deployment.deploy-dev—development deployment.
If using a custom template, commit it to version control:
git add .Taskfile.template
git commit -m "Add custom Taskfile template"Optionally create a .taskfile-data.yaml file to display service URLs in the dev task. See Taskfile data configuration for complete documentation.
If your template uses custom variables, document them:
# .Taskfile.template
#
# Custom variables:
# - PROJECT_NAME: Set in .env
# - DEPLOY_TARGET: Set in .env
#
version: '3'
# ...After modifying a template, regenerate and test:
dr task compose --template .Taskfile.template
task --list
task devTemplate authors can provide additional configuration for Taskfile generation by creating a .taskfile-data.yaml file in the template root directory.
my-template/
├── .env
├── .taskfile-data.yaml # Configuration file
├── Taskfile.yaml # Generated
└── components/
# .taskfile-data.yaml
# Optional configuration for dr task compose
# Development server ports
# Displayed when running the dev task
ports:
- name: Backend API
port: 8080
- name: Frontend
port: 5173
- name: Worker Service
port: 8842
- name: MCP Server
port: 9000Purpose:
The ports array allows template authors to specify which ports their services use. When developers run task dev, they see URLs for each service.
Example output:
When developers run task dev with port configuration:
task mcp_server:dev &
sleep 3
task web:dev &
sleep 3
task agent:dev &
sleep 3
task frontend_web:dev &
sleep 8
✅ All servers started!
🔗 Backend API: http://localhost:8080
🔗 Frontend: http://localhost:5173
🔗 Agent Service: http://localhost:8842
🔗 MCP Server: http://localhost:9000
DataRobot Notebook integration:
The generated dev task automatically detects DataRobot Notebook environments and adjusts URLs:
🔗 Backend API: https://app.datarobot.com/notebook-sessions/abc123/ports/8080
🔗 Frontend: https://app.datarobot.com/notebook-sessions/abc123/ports/5173
This happens automatically when the NOTEBOOK_ID environment variable is present.
Benefits:
- Improved onboarding—new developers immediately know where services are running.
- Self-documenting—ports are visible in generated Taskfile and command output.
- Notebook support—URLs work correctly in DataRobot Notebooks.
- Reduced confusion—no need to check logs or documentation for port numbers.
Best practices:
- List all services—include every service that starts in dev mode.
- Use descriptive names—"Backend API" is clearer than "Backend".
- Match actual ports—ensure ports match what's in component Taskfiles.
- Update when changing—keep configuration in sync with service changes.
Use .taskfile-data.yaml when:
- Your template has multiple services with different ports.
- Services use non-standard ports that aren't obvious.
- You want to improve developer experience.
- Your template targets DataRobot Notebooks.
You can skip it when:
- Your template has a single service.
- Ports are obvious or standard (e.g., 3000 for Node.js).
- You use custom Taskfile templates with hardcoded values.
- Port information is already well-documented elsewhere.
The .taskfile-data.yaml file is completely optional. If not present:
- The dev task still works correctly.
- Services start normally.
- Port URLs simply aren't displayed.
This allows template authors to add port configuration incrementally without breaking existing templates.
The .taskfile-data.yaml file uses an extensible format. Future CLI versions may support additional configuration options such as:
- Custom environment variables for templates.
- Service metadata (descriptions, dependencies).
- Deployment configuration.
- Build optimization hints.
Template authors can future-proof their templates by using this configuration file even if only specifying ports initially.
Minimal example:
# .taskfile-data.yaml
ports:
- name: App
port: 8000Full-stack application:
# .taskfile-data.yaml
ports:
- name: Backend API
port: 8080
- name: Frontend
port: 5173
- name: Database Admin
port: 8081
- name: Redis Commander
port: 8082Microservices architecture:
# .taskfile-data.yaml
ports:
- name: API Gateway
port: 8080
- name: Auth Service
port: 8081
- name: User Service
port: 8082
- name: Order Service
port: 8083
- name: Frontend
port: 3000
- name: Admin Dashboard
port: 3001# Set up template (clones and configures)
dr templates setup
cd my-app
# Set up environment
dr dotenv setup
# Generate Taskfile
dr task compose
# View available tasks
task --list# Add new component
mkdir new-service
cat > new-service/Taskfile.yaml << 'EOF'
version: '3'
tasks:
dev:
desc: Start new service
cmds:
- echo "Starting service..."
EOF
# Regenerate Taskfile
dr task compose
# Run all services
task devWhen components change:
# Regenerate Taskfile
dr task compose
# Verify new structure
task --listList all available tasks from composed Taskfile.
dr task list [flags]Lists all tasks available in the current template, including tasks from all component Taskfiles.
# List all tasks
dr task list
# Show with full task tree
task --list-allExecute template tasks. This is an alias for dr run.
dr task run [TASK_NAME...] [flags]Execute one or more tasks defined in component Taskfiles. See dr run for full documentation.
# Run single task
dr task run dev
# Run multiple tasks
dr task run lint test
# Run in parallel
dr task run lint test --parallel- dr run—task execution documentation.
- Template system—template structure overview.
- Environment variables—configuration management.
- Task documentation—official Task runner documentation.