Command-line interface for deploying and managing ETLR workflows.
Quick reference: See QUICKSTART.md for command cheat sheet.
- Installation
- Authentication
- Quick Start
- Environment Variables
- Stage Management
- Commands
- Version Management
- CI/CD Integration
- Development
pip install etlrGet your API key from the ETLR dashboard: https://app.etlr.io/developer
Set your API key once in your shell configuration:
# Add to ~/.zshrc or ~/.bashrc
export ETLR_API_KEY=your_api_key_hereReload your shell or run:
source ~/.zshrc # or ~/.bashrcOverride or specify per-command:
etlr --api-key your_api_key_here listPriority: CLI flag > ETLR_API_KEY environment variable
# workflow.yaml
name: hello-world
stage: dev
input:
type: http_webhook
steps:
- type: print
message: "Hello from ${input.data}!"etlr deploy workflow.yamlOutput:
Pushing workflow...
✓ Workflow created: hello-world/dev
Deploying workflow...
✓ Workflow deployed and running
etlr status --name hello-world --stage devetlr listThat's it! Your workflow is running.
Declare environment variables in your workflow YAML, and the CLI automatically gathers them from your shell environment.
1. Declare in workflow.yaml:
workflow:
name: data-processor
stage: dev
environment:
- name: API_KEY
secret: true
- name: DATABASE_URL
secret: true
- name: LOG_LEVEL
input:
type: http_webhook
steps:
- type: http_call
url: https://api.example.com/data
headers:
Authorization: "Bearer ${env:API_KEY}"2. Set values in your shell:
export API_KEY=sk-abc123...
export DATABASE_URL=postgres://...
export LOG_LEVEL=info3. Deploy:
etlr deploy workflow.yamlOutput:
Environment variables:
API_KEY: *** (secret)
DATABASE_URL: *** (secret)
LOG_LEVEL: info
Pushing workflow...
✓ Workflow deployed
Mark sensitive values as secret: true to hide them in CLI output:
environment:
- name: API_KEY
secret: true # Shows as ***
- name: LOG_LEVEL
secret: false # Shows actual value
- name: TIMEOUT # Defaults to falseOverride declared env vars or add new ones with -e flag:
# Override
etlr deploy workflow.yaml -e API_KEY=different-key
# Add new variable
etlr deploy workflow.yaml -e EXTRA_VAR=value
# Multiple overrides
etlr deploy workflow.yaml -e API_KEY=xxx -e LOG_LEVEL=debugIf required env vars are missing, deployment fails with a helpful error:
$ etlr deploy workflow.yaml
Error: Missing required environment variables: API_KEY, DATABASE_URL
Set them with:
export API_KEY=value
export DATABASE_URL=value
Or use -e flags:
etlr deploy workflow.yaml -e API_KEY=value -e DATABASE_URL=value- ✅ Self-documenting - Anyone reading YAML knows what's needed
- ✅ Validated - Missing vars caught before deployment
- ✅ No CLI clutter - No need for multiple
-eflags - ✅ Version controlled - Variable names (not values) in git
- ✅ Team friendly - New developers see requirements immediately
Stages (dev, staging, prod) let you run different versions of the same workflow in different environments.
Priority (highest to lowest):
--stageCLI flag (explicit override)ETLR_STAGEenvironment variable (session default)stagefield in YAML (file default)${env:STAGE}in YAML (dynamic from environment)
name: my-workflow
stage: devetlr deploy workflow.yaml # Uses 'dev'
etlr deploy workflow.yaml --stage prod # Override to 'prod'Use when: Single environment or simple setup
# Set once for your session
export ETLR_STAGE=dev
# Deploy without specifying stage
etlr deploy workflow.yaml # Uses 'dev'
# Override when needed
etlr deploy workflow.yaml --stage prodAdd to ~/.zshrc for persistence:
export ETLR_STAGE=dev
export ETLR_API_KEY=your_dev_keyUse when: Local development with occasional prod deploys
name: my-workflow
stage: ${env:STAGE} # or ${env:STAGE, dev} with defaultSTAGE=dev etlr deploy workflow.yaml
STAGE=prod etlr deploy workflow.yamlUse when: CI/CD or multiple environments
etlr deploy workflow.yaml --stage staging
etlr deploy workflow.yaml --stage prodUse when: CI/CD pipelines or when you want explicit control
Local Development:
# ~/.zshrc
export ETLR_STAGE=dev
export ETLR_API_KEY=dev_key
# Just deploy
cd my-project
etlr deploy workflow.yamlCI/CD:
# .github/workflows/deploy.yml
- name: Deploy to staging
run: etlr deploy workflow.yaml --stage staging
env:
ETLR_API_KEY: ${{ secrets.STAGING_API_KEY }}
- name: Deploy to production
run: etlr deploy workflow.yaml --stage prod
env:
ETLR_API_KEY: ${{ secrets.PROD_API_KEY }}Team with .env files:
# .env.dev
ETLR_STAGE=dev
ETLR_API_KEY=dev_key
# .env.prod
ETLR_STAGE=prod
ETLR_API_KEY=prod_key
# Deploy
source .env.dev && etlr deploy workflow.yaml
source .env.prod && etlr deploy workflow.yamletlr listCreates/updates and starts a workflow in one command.
# From file
etlr deploy workflow.yaml
# From workflow.yaml in current directory
etlr deploy
# Override stage
etlr deploy workflow.yaml --stage prod
# With environment variables
etlr deploy workflow.yaml -e API_KEY=xxx -e LOG_LEVEL=debug
# By identifier (if already pushed)
etlr deploy --id <workflow-uuid>
etlr deploy --name my-workflow --stage prod# By ID
etlr get --id <workflow-uuid>
# By name and stage
etlr get --name my-workflow --stage prodStart a workflow that was previously stopped or pushed but not started.
etlr start --id <workflow-uuid>
etlr start --name my-workflow --stage prodetlr stop --id <workflow-uuid>
etlr stop --name my-workflow --stage prodetlr status --id <workflow-uuid>
etlr status --name my-workflow --stage prodOutput shows health status with color coding:
- 🟢 Green: Running normally
- 🟡 Yellow: Paused or warning
- 🔴 Red: Error or stopped
View workflow execution logs to debug issues or monitor activity.
# View recent logs (last 100 lines by default)
etlr logs --name my-workflow --stage prod
etlr logs --id <workflow-uuid>
# Specify number of lines
etlr logs --name my-workflow --stage prod --lines 200
etlr logs --id <workflow-uuid> -n 500
# Raw output (no formatting)
etlr logs --name my-workflow --stage prod --rawOutput features:
- Color-coded log levels (ERROR=red, WARN=yellow, INFO=blue, DEBUG=white)
- Timestamps for each log entry
- Formatted display showing level and message
- Raw mode for piping to other tools
Example output:
=== Logs for my-workflow/prod (last 100 lines) ===
2024-01-15T10:00:00Z [INFO] Workflow started
2024-01-15T10:00:01Z [DEBUG] Processing event data
2024-01-15T10:00:02Z [INFO] HTTP request completed successfully
2024-01-15T10:00:03Z [WARN] Rate limit approaching
2024-01-15T10:00:04Z [ERROR] Failed to connect to database
# With confirmation prompt
etlr delete --id <workflow-uuid>
etlr delete --name my-workflow --stage prod
# Skip confirmation (for scripts)
etlr delete --name my-workflow --stage prod --yesETLR automatically versions workflows on each deploy. You can list, view, and restore previous versions.
etlr versions --id <workflow-uuid>Output:
Versions for workflow abc-123:
Version 3 (current) - 2025-12-17 14:23:10
Version 2 - 2025-12-17 12:15:43
Version 1 - 2025-12-16 09:30:22
etlr get-version --id <workflow-uuid> --version 2# With confirmation
etlr restore --id <workflow-uuid> --version 2
# Skip confirmation
etlr restore --id <workflow-uuid> --version 2 --yesThis creates a new version (e.g., version 4) with the content from version 2.
name: Deploy Workflow
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install ETLR CLI
run: pip install etlr
- name: Deploy to staging
if: github.ref == 'refs/heads/main'
run: etlr deploy workflow.yaml --stage staging
env:
ETLR_API_KEY: ${{ secrets.STAGING_API_KEY }}
- name: Deploy to production
if: github.ref == 'refs/heads/main' && github.event_name == 'release'
run: etlr deploy workflow.yaml --stage prod
env:
ETLR_API_KEY: ${{ secrets.PROD_API_KEY }}stages:
- deploy
deploy_staging:
stage: deploy
script:
- pip install etlr
- etlr deploy workflow.yaml --stage staging
environment:
name: staging
variables:
ETLR_API_KEY: $STAGING_API_KEY
deploy_production:
stage: deploy
script:
- pip install etlr
- etlr deploy workflow.yaml --stage prod
environment:
name: production
variables:
ETLR_API_KEY: $PROD_API_KEY
when: manual- Store API keys in secret managers (
ETLR_API_KEY) - Use
--stageflag for explicit environment targeting - Use
--yesflag to skip confirmations - Set timeouts for deployment commands
- Add status checks after deployment
git clone https://github.com/etlr-io/cli.git
cd cli
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"etlr --helppytest
pytest -v # Verbose
pytest tests/test_cli.py # Specific file# Format
black src tests
# Lint
ruff check src tests
# Type check
mypy src# Update version in pyproject.toml
# Commit and tag
git tag v1.2.3
git push origin v1.2.3
# Build and publish
python -m build
twine upload dist/*Use .env files or direnv for project-specific settings:
# .env
ETLR_API_KEY=project_specific_key
ETLR_STAGE=dev
# Load and deploy
source .env
etlr deploy workflow.yamlOr use direnv to auto-load when entering directory:
# .envrc
export ETLR_API_KEY=project_key
export ETLR_STAGE=devSwitch between accounts with CLI flag:
# Production account
etlr --api-key $PROD_KEY deploy workflow.yaml
# Staging account
etlr --api-key $STAGING_KEY deploy workflow.yamlCreate shell aliases for common workflows:
# ~/.zshrc
alias deploy-prod='etlr deploy workflow.yaml --stage prod'
alias deploy-dev='etlr deploy workflow.yaml --stage dev'
alias check-prod='etlr status --name my-workflow --stage prod'Enable verbose output (when available):
etlr --debug deploy workflow.yamlOr check workflow logs via the web dashboard.
- Quick reference: QUICKSTART.md
- Issues: https://github.com/etlr-io/cli/issues
- Documentation: https://etlr.io/docs/
MIT