Instantly share code, notes, and snippets.
Last active
November 22, 2025 08:54
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save Goldziher/88bf98d71abdd6be7f42f996396a02a9 to your computer and use it in GitHub Desktop.
Taskfile.yaml Shared Conventions - Universal patterns for Task automation across polyglot projects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # TASKFILE SHARED CONVENTIONS | |
| # Central repository for Taskfile.yaml patterns across all projects | |
| # Use this as a reference when standardizing Taskfile.yaml files | |
| version: '3' | |
| # ============================================================================== | |
| # UNIVERSAL TASK NAMING CONVENTIONS | |
| # ============================================================================== | |
| # CORE LIFECYCLE TASKS (all projects should have these) | |
| # - setup : One-time project initialization (install deps, create .env, etc.) | |
| # MUST be idempotent and safe to re-run multiple times | |
| # - update : Update all dependencies to latest versions (cargo upgrade, uv-bump, pnpm up --latest) | |
| # CRITICAL task for dependency management | |
| # - dev : Start development environment (servers, watchers, etc.) | |
| # - build : Build all artifacts (production-ready) | |
| # - test : Run all tests (unit + integration, no coverage) | |
| # - test:coverage : Run tests with coverage reporting | |
| # - check : Run both lint:check AND format:check (no modifications, CI-friendly) | |
| # - lint : Run all linters WITH auto-fix enabled | |
| # - lint:check : Run all linters WITHOUT auto-fix (check-only mode) | |
| # - format : Auto-format all code (with modifications) | |
| # - format:check : Check formatting without modifying files (CI-friendly) | |
| # - clean : Remove build artifacts and caches | |
| # - clean:all : Deep clean including dependencies | |
| # LANGUAGE-SPECIFIC NAMESPACE CONVENTIONS | |
| # Each language should use its own namespace with consistent sub-tasks: | |
| # rust: | |
| # - rust:install : Install Rust toolchain (if needed) | |
| # - rust:update : cargo upgrade --incompatible && cargo update | |
| # - rust:build : Cargo build (debug or release) | |
| # - rust:test : Cargo test | |
| # - rust:test:coverage : Coverage with tarpaulin/llvm-cov | |
| # - rust:check : cargo check && clippy WITHOUT auto-fix | |
| # - rust:lint : cargo fmt && clippy WITH auto-fix (if applicable) | |
| # - rust:lint:check : cargo fmt --check && clippy (check-only) | |
| # - rust:format : cargo fmt (with modifications) | |
| # - rust:format:check : cargo fmt --check (no modifications) | |
| # - rust:doc : Generate rustdoc | |
| # - rust:bench : Run benchmarks (criterion) | |
| # - rust:clean : Cargo clean | |
| # python: | |
| # - python:install : uv venv + uv sync | |
| # - python:update : uv-bump + uv sync --upgrade | |
| # - python:setup : Alias for python:install (idempotent) | |
| # - python:test : pytest (function-based, *_test.py) | |
| # - python:test:coverage : pytest with coverage (95%+ target) | |
| # - python:lint : ruff check --fix (WITH auto-fix) | |
| # - python:lint:check : ruff check (WITHOUT auto-fix) | |
| # - python:format : ruff format (with modifications) | |
| # - python:format:check: ruff format --check (no modifications) | |
| # - python:typecheck : mypy --strict | |
| # - python:clean : Remove __pycache__, .pytest_cache, .mypy_cache | |
| # typescript: (or ts:, node:, frontend:) | |
| # - typescript:install : pnpm install | |
| # - typescript:update : pnpm up --latest -r | |
| # - typescript:setup : Alias for typescript:install (idempotent) | |
| # - typescript:dev : Next.js dev server / Vite dev | |
| # - typescript:build : Production build | |
| # - typescript:test : vitest (*.spec.ts next to source) | |
| # - typescript:lint : biome lint --write (WITH auto-fix) | |
| # - typescript:lint:check: biome lint (WITHOUT auto-fix) | |
| # - typescript:format : biome format --write (with modifications) | |
| # - typescript:format:check : biome format (no modifications) | |
| # - typescript:typecheck : tsc --noEmit | |
| # - typescript:clean : Remove node_modules, .next, dist | |
| # go: | |
| # - go:install : go mod download | |
| # - go:update : go get -u ./... && go mod tidy + update golangci-lint | |
| # - go:build : go build | |
| # - go:test : go test (table-driven, *_test.go with _test package) | |
| # - go:test:coverage : go test -cover | |
| # - go:lint : golangci-lint run --fix (WITH auto-fix) | |
| # - go:lint:check : golangci-lint run (WITHOUT auto-fix) | |
| # - go:format : gofmt -w / goimports -w (with modifications) | |
| # - go:format:check : gofmt -l / goimports -l (check-only) | |
| # - go:clean : Remove binaries | |
| # ruby: | |
| # - ruby:install : bundle install | |
| # - ruby:update : bundle update | |
| # - ruby:setup : Alias for ruby:install (idempotent) | |
| # - ruby:test : rspec | |
| # - ruby:lint : rubocop --autocorrect-all (WITH auto-fix) | |
| # - ruby:lint:check : rubocop (WITHOUT auto-fix) | |
| # - ruby:format : Alias for ruby:lint (rubocop handles formatting) | |
| # - ruby:format:check: Alias for ruby:lint:check | |
| # - ruby:typecheck : steep check (RBS files in sig/) | |
| # - ruby:clean : Remove .bundle | |
| # java: | |
| # - java:install : Maven/Gradle dependency resolution | |
| # - java:update : mvn versions:use-latest-releases / gradle dependencyUpdates | |
| # - java:setup : Alias for java:install (idempotent) | |
| # - java:build : mvn compile / gradle build | |
| # - java:test : mvn test / gradle test (JUnit 5) | |
| # - java:lint : checkstyle + PMD WITH auto-fix (where applicable) | |
| # - java:lint:check : checkstyle + PMD WITHOUT auto-fix | |
| # - java:format : google-java-format --replace (with modifications) | |
| # - java:format:check: google-java-format --dry-run (check-only) | |
| # - java:clean : mvn clean / gradle clean | |
| # php: | |
| # - php:install : composer install | |
| # - php:update : composer update | |
| # - php:setup : Alias for php:install (idempotent) | |
| # - php:test : phpunit | |
| # - php:lint : phpstan analyse + phpcbf (WITH auto-fix via phpcbf) | |
| # - php:lint:check : phpstan analyse + phpcs (WITHOUT auto-fix) | |
| # - php:format : phpcbf (with modifications, PSR-12) | |
| # - php:format:check : phpcs (check-only, PSR-12) | |
| # - php:clean : Remove vendor | |
| # ============================================================================== | |
| # CROSS-CUTTING NAMESPACE CONVENTIONS | |
| # ============================================================================== | |
| # db: (database operations) | |
| # - db:setup : Create databases and run migrations | |
| # - db:migrate : Run pending migrations | |
| # - db:migrate:rollback : Rollback last migration | |
| # - db:seed : Seed with fixture data | |
| # - db:reset : Drop, recreate, migrate, seed | |
| # - db:console : Open database REPL | |
| # docker: | |
| # - docker:build : Build all Docker images | |
| # - docker:up : Start all services (docker compose up) | |
| # - docker:down : Stop all services | |
| # - docker:logs : Tail logs | |
| # - docker:clean : Remove containers, volumes, images | |
| # fixture: (test data generation) | |
| # - fixture:generate : Generate test fixtures from schemas | |
| # - fixture:validate : Validate fixtures against schemas | |
| # - fixture:sync : Sync fixtures across languages | |
| # ci: (CI/CD operations) | |
| # - ci:validate : Run all validation steps locally | |
| # - ci:build : CI build simulation | |
| # - ci:test : CI test simulation | |
| # release: (versioning and publishing) | |
| # - release:version : Bump version across manifests | |
| # - release:publish : Publish to registries (crates.io, PyPI, npm, etc.) | |
| # - release:tag : Create git tag | |
| # ============================================================================== | |
| # VARIABLE CONVENTIONS | |
| # ============================================================================== | |
| vars: | |
| # Project metadata | |
| PROJECT_NAME: "project-name" | |
| VERSION: | |
| sh: grep '^version = ' Cargo.toml | sed 's/.*"\(.*\)".*/\1/' # or from package.json, etc. | |
| # Build configuration | |
| BUILD_DIR: "build" | |
| DIST_DIR: "dist" | |
| TARGET_DIR: "target" | |
| # Rust configuration | |
| CARGO_TARGET_DIR: "{{.TARGET_DIR}}" | |
| RUST_LOG: "info" | |
| RUSTFLAGS: "-D warnings" | |
| # Python configuration | |
| PYTHON_VERSION: "3.10" | |
| UV_SYSTEM_PYTHON: "1" | |
| PYTEST_ARGS: "-v --tb=short" | |
| COVERAGE_TARGET: "95" | |
| # TypeScript/Node configuration | |
| NODE_ENV: "development" | |
| PNPM_VERSION: "10.17" | |
| # Database configuration | |
| DATABASE_URL: "postgresql://localhost/{{.PROJECT_NAME}}_dev" | |
| TEST_DATABASE_URL: "postgresql://localhost/{{.PROJECT_NAME}}_test" | |
| # Docker configuration | |
| COMPOSE_FILE: "docker-compose.yaml" | |
| COMPOSE_PROJECT_NAME: "{{.PROJECT_NAME}}" | |
| # Cross-platform detection | |
| OS: | |
| sh: uname -s | tr '[:upper:]' '[:lower:]' | |
| ARCH: | |
| sh: uname -m | |
| # ============================================================================== | |
| # DEPENDENCY PATTERN CONVENTIONS | |
| # ============================================================================== | |
| # Pattern 1: Sequential dependencies with deps: | |
| # tasks: | |
| # build: | |
| # deps: [lint, test] | |
| # cmds: | |
| # - cargo build --release | |
| # Pattern 2: Parallel execution (default) | |
| # tasks: | |
| # ci: | |
| # cmds: | |
| # - task: rust:lint | |
| # - task: rust:test | |
| # - task: python:lint | |
| # - task: python:test | |
| # Pattern 3: Conditional execution with status: | |
| # tasks: | |
| # setup: | |
| # cmds: | |
| # - pnpm install | |
| # status: | |
| # - test -f node_modules/.bin/next | |
| # Pattern 4: Platform-specific with platforms: | |
| # tasks: | |
| # rust:build: | |
| # platforms: [darwin, linux] | |
| # cmds: | |
| # - cargo build --release | |
| # ============================================================================== | |
| # COMMAND PATTERNS | |
| # ============================================================================== | |
| # Pattern 1: Fail-fast with set -e | |
| # cmds: | |
| # - cmd: | | |
| # set -e | |
| # cargo build | |
| # cargo test | |
| # Pattern 2: Silent commands with silent: true | |
| # tasks: | |
| # version: | |
| # silent: true | |
| # cmds: | |
| # - echo "{{.VERSION}}" | |
| # Pattern 3: Error handling with ignore_error | |
| # tasks: | |
| # clean: | |
| # cmds: | |
| # - cmd: rm -rf target | |
| # ignore_error: true | |
| # Pattern 4: Multi-line with YAML block scalar | |
| # cmds: | |
| # - | | |
| # echo "Starting build..." | |
| # cargo build --release | |
| # echo "Build complete" | |
| # ============================================================================== | |
| # CROSS-PLATFORM SUPPORT PATTERNS | |
| # ============================================================================== | |
| # Pattern 1: OS-specific variables | |
| # vars: | |
| # PYTHON_BIN: | |
| # sh: | | |
| # if [ "{{OS}}" = "darwin" ]; then | |
| # echo ".venv/bin/python" | |
| # else | |
| # echo ".venv/bin/python3" | |
| # fi | |
| # Pattern 2: Platform-specific tasks | |
| # tasks: | |
| # setup:darwin: | |
| # platforms: [darwin] | |
| # cmds: | |
| # - brew install task | |
| # | |
| # setup:linux: | |
| # platforms: [linux] | |
| # cmds: | |
| # - curl -sL https://taskfile.dev/install.sh | sh | |
| # ============================================================================== | |
| # CORE TASK IMPLEMENTATION EXAMPLES | |
| # ============================================================================== | |
| # Example: setup task (MUST be idempotent) | |
| # tasks: | |
| # setup: | |
| # desc: "Install all dependencies and initialize project" | |
| # cmds: | |
| # - task: rust:install | |
| # - task: python:install | |
| # - task: typescript:install | |
| # - task: ruby:install | |
| # - echo "✓ Setup complete - safe to re-run anytime" | |
| # status: | |
| # - test -f .env # Only create .env if missing | |
| # Example: update task (updates all dependencies) | |
| # tasks: | |
| # update: | |
| # desc: "Update all dependencies to latest versions" | |
| # cmds: | |
| # - echo "Updating Rust dependencies..." | |
| # - task: rust:update | |
| # - echo "Updating Python dependencies..." | |
| # - task: python:update | |
| # - echo "Updating TypeScript dependencies..." | |
| # - task: typescript:update | |
| # - prek autoupdate # Update pre-commit hooks | |
| # - echo "✓ All dependencies updated" | |
| # Example: check task (CI-friendly, no modifications) | |
| # tasks: | |
| # check: | |
| # desc: "Run all checks without modifications (lint + format checks)" | |
| # cmds: | |
| # - task: lint:check | |
| # - task: format:check | |
| # Example: lint task (WITH auto-fix) | |
| # tasks: | |
| # lint: | |
| # desc: "Run all linters with auto-fix enabled" | |
| # cmds: | |
| # - task: rust:lint | |
| # - task: python:lint | |
| # - task: typescript:lint | |
| # - task: go:lint | |
| # Example: lint:check task (WITHOUT auto-fix) | |
| # tasks: | |
| # lint:check: | |
| # desc: "Run all linters in check-only mode (no modifications)" | |
| # cmds: | |
| # - task: rust:lint:check | |
| # - task: python:lint:check | |
| # - task: typescript:lint:check | |
| # - task: go:lint:check | |
| # Example: format task (WITH modifications) | |
| # tasks: | |
| # format: | |
| # desc: "Format all code with modifications" | |
| # cmds: | |
| # - task: rust:format | |
| # - task: python:format | |
| # - task: typescript:format | |
| # - task: go:format | |
| # Example: format:check task (WITHOUT modifications) | |
| # tasks: | |
| # format:check: | |
| # desc: "Check code formatting without modifications" | |
| # cmds: | |
| # - task: rust:format:check | |
| # - task: python:format:check | |
| # - task: typescript:format:check | |
| # - task: go:format:check | |
| # ============================================================================== | |
| # PROJECT TYPE SPECIFIC PATTERNS | |
| # ============================================================================== | |
| # POLYGLOT PROJECTS (kreuzberg, html-to-markdown) | |
| # - Version sync from single source (Cargo.toml) | |
| # - Parallel builds for all bindings | |
| # - Unified test:all that runs tests in all languages | |
| # - E2E test generation from fixtures | |
| # - FFI library builds with LD_LIBRARY_PATH management | |
| # MONOREPO PROJECTS (fincom, pronestic) | |
| # - Service-specific namespaces (backend:, frontend:, indexer:) | |
| # - Docker Compose orchestration for all services | |
| # - Database per service with multi-schema support | |
| # - Environment profiles (dev, staging, prod) | |
| # WEB FRAMEWORK PROJECTS (spikard) | |
| # - Benchmark harness with criterion | |
| # - Fixture-driven test generation | |
| # - OpenAPI code generation | |
| # - Integration tests with real HTTP server | |
| # FULL-STACK PROJECTS (grantflow) | |
| # - Frontend + backend coordination | |
| # - Cloud SQL remote management | |
| # - E2E environment with emulators | |
| # - Multi-tenant data isolation | |
| # ============================================================================== | |
| # BEST PRACTICES | |
| # ============================================================================== | |
| # 1. Task naming: lowercase with colons (namespace:task:subtask) | |
| # 2. Description on all public tasks (desc: "...") | |
| # 3. Internal tasks with prefix 'internal:' or hidden via 'internal: true' | |
| # 4. Variables in SCREAMING_SNAKE_CASE | |
| # 5. Use {{.VAR}} for templating, not $VAR | |
| # 6. Prefer task: over direct command invocation for composition | |
| # 7. Always specify working dir if not root (dir: "path") | |
| # 8. Use sources: and generates: for incremental builds | |
| # 9. Group related tasks in namespaces | |
| # 10. Lock files (uv.lock, pnpm-lock.yaml) should be committed | |
| # 11. setup task should be idempotent (safe to run multiple times) | |
| # 12. clean should not delete lock files or .env | |
| # 13. Use silent: true for tasks that output structured data | |
| # 14. Avoid hard-coded paths; use variables | |
| # ============================================================================== | |
| # ANTI-PATTERNS TO AVOID | |
| # ============================================================================== | |
| # ❌ DON'T: Use shell-specific syntax (use POSIX sh) | |
| # ❌ DON'T: Hard-code absolute paths | |
| # ❌ DON'T: Mix concerns in single task (lint + test + build) | |
| # ❌ DON'T: Skip error handling (use set -e or ignore_error intentionally) | |
| # ❌ DON'T: Create circular dependencies between tasks | |
| # ❌ DON'T: Use non-descriptive task names (a, b, run1, etc.) | |
| # ❌ DON'T: Duplicate commands across tasks (extract to shared task) | |
| # ❌ DON'T: Ignore cross-platform compatibility | |
| # ❌ DON'T: Use deprecated Task v2 syntax | |
| # ❌ DON'T: Commit .env files (use .env.example) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment