mirror of
https://github.com/Routstr/routstr-core.git
synced 2026-07-22 12:22:20 +00:00
CI runs 'uv run mypy .' while the Makefile only checked routstr/, so test files could pass locally and fail the pipeline. lint, type-check and ci-lint now check everything; --ignore-missing-imports is dropped since the CI invocation passes without it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
286 lines
9.8 KiB
Makefile
286 lines
9.8 KiB
Makefile
# Makefile for Routstr Proxy
|
|
|
|
# Detect if we're in a virtual environment
|
|
VENV_EXISTS := $(shell test -d .venv && echo 1)
|
|
ifeq ($(VENV_EXISTS), 1)
|
|
PYTHON := .venv/bin/python
|
|
PYTEST := .venv/bin/pytest
|
|
RUFF := .venv/bin/ruff
|
|
MYPY := .venv/bin/mypy
|
|
ALEMBIC := .venv/bin/alembic
|
|
else
|
|
PYTHON := python
|
|
PYTEST := pytest
|
|
RUFF := ruff
|
|
MYPY := mypy
|
|
ALEMBIC := alembic
|
|
endif
|
|
|
|
.PHONY: help setup test test-unit test-integration test-integration-docker test-all test-fast test-performance clean docker-up docker-down lint format type-check dev-setup check-deps db-upgrade db-downgrade db-current db-history db-migrate db-revision db-heads db-clean ui-build ui-build-docker ui-dev
|
|
|
|
# Default target
|
|
help:
|
|
@echo "Available targets:"
|
|
@echo " make test - Run all tests (unit + integration with mocks)"
|
|
@echo " make test-unit - Run unit tests only"
|
|
@echo " make test-integration - Run integration tests with mocks (fast)"
|
|
@echo " make test-integration-docker - Run integration tests with Docker services"
|
|
@echo " make test-all - Run all tests including Docker integration"
|
|
@echo " make test-fast - Run fast tests only (skip slow tests)"
|
|
@echo " make test-performance - Run performance tests"
|
|
@echo " make docker-up - Start Docker test services"
|
|
@echo " make docker-down - Stop Docker test services"
|
|
@echo " make clean - Clean up test artifacts and caches"
|
|
@echo " make lint - Run linting checks"
|
|
@echo " make format - Format code with ruff"
|
|
@echo " make type-check - Run mypy type checking"
|
|
@echo " make dev-setup - Set up development environment"
|
|
@echo " make check-deps - Check system dependencies"
|
|
@echo " make setup - First-time project setup"
|
|
@echo ""
|
|
@echo "UI targets:"
|
|
@echo " make ui-build - Build UI for production (static export)"
|
|
@echo " make ui-build-docker - Build UI using Docker (no Node.js needed)"
|
|
@echo " make ui-dev - Start UI development server"
|
|
@echo ""
|
|
@echo "Docker UI build requires only Docker, no local Node.js installation needed."
|
|
@echo "Database migration shortcuts:"
|
|
@echo " make create-migration - Auto-generate new migration"
|
|
@echo " make db-upgrade - Apply all pending migrations"
|
|
@echo " make db-downgrade - Downgrade one migration"
|
|
|
|
# First-time setup
|
|
setup: check-deps dev-setup
|
|
@echo ""
|
|
@echo "🎉 Setup complete! Next steps:"
|
|
@echo " 1. Run tests: make test"
|
|
@echo " 2. Run integration: make test-integration-docker"
|
|
@echo " 3. Start developing!"
|
|
|
|
# Test targets
|
|
test: test-unit test-integration
|
|
|
|
test-unit:
|
|
@echo "🧪 Running unit tests..."
|
|
$(PYTEST) tests/unit/ -v
|
|
|
|
test-integration:
|
|
@echo "🎭 Running integration tests with mocks..."
|
|
$(PYTEST) tests/integration/ -v
|
|
|
|
test-integration-docker:
|
|
@echo "🐳 Running integration tests with Docker services..."
|
|
./tests/run_integration.py
|
|
|
|
test-all: test-unit test-integration-docker
|
|
|
|
test-fast:
|
|
@echo "⚡ Running fast tests only..."
|
|
$(PYTEST) -m "not slow and not requires_docker" -v
|
|
|
|
test-performance:
|
|
@echo "📊 Running performance tests..."
|
|
$(PYTEST) tests/integration/ -m "performance" -v -s
|
|
|
|
# Docker management
|
|
docker-up:
|
|
@echo "🚀 Starting Docker test services..."
|
|
docker-compose -f compose.testing.yml up -d
|
|
@echo "Waiting for services to be ready..."
|
|
@sleep 5
|
|
@echo "Services started. Run 'make test-integration-docker' to test."
|
|
|
|
docker-down:
|
|
@echo "🛑 Stopping Docker test services..."
|
|
docker-compose -f compose.testing.yml down -v
|
|
|
|
# Code quality
|
|
lint:
|
|
@echo "🔍 Running linting checks..."
|
|
$(RUFF) check .
|
|
$(MYPY) .
|
|
|
|
format:
|
|
@echo "✨ Formatting code..."
|
|
$(RUFF) format .
|
|
$(RUFF) check --fix .
|
|
|
|
type-check:
|
|
@echo "🔎 Running type checks..."
|
|
$(MYPY) .
|
|
|
|
# Development setup
|
|
dev-setup:
|
|
@echo "🔧 Setting up development environment..."
|
|
@# Check if uv is installed
|
|
@if ! command -v uv >/dev/null 2>&1; then \
|
|
echo "📦 uv not found. Installing uv..."; \
|
|
if command -v curl >/dev/null 2>&1; then \
|
|
curl -LsSf https://astral.sh/uv/install.sh | sh; \
|
|
elif command -v pip >/dev/null 2>&1; then \
|
|
pip install uv; \
|
|
else \
|
|
echo "❌ Neither curl nor pip found. Please install uv manually:"; \
|
|
echo " Visit https://docs.astral.sh/uv/getting-started/installation/"; \
|
|
exit 1; \
|
|
fi; \
|
|
echo "✅ uv installed successfully!"; \
|
|
else \
|
|
echo "✅ uv is already installed (version: $$(uv --version))"; \
|
|
fi
|
|
uv sync --dev
|
|
uv pip install -e .
|
|
@echo "✅ Development environment ready!"
|
|
|
|
# Check dependencies
|
|
check-deps:
|
|
@echo "🔍 Checking system dependencies..."
|
|
@echo ""
|
|
@echo "Core tools:"
|
|
@printf " %-18s" "Python:"; if command -v python >/dev/null 2>&1; then python --version; else echo "❌ Not found"; fi
|
|
@printf " %-18s" "uv:"; if command -v uv >/dev/null 2>&1; then uv --version; else echo "❌ Not found - run 'make dev-setup' to install"; fi
|
|
@printf " %-18s" "Docker:"; if command -v docker >/dev/null 2>&1; then docker --version; else echo "⚠️ Not found (optional, needed for integration tests)"; fi
|
|
@printf " %-18s" "Docker Compose:"; if command -v docker-compose >/dev/null 2>&1; then docker-compose --version; else echo "⚠️ Not found (optional, needed for integration tests)"; fi
|
|
@echo ""
|
|
@echo "Development tools:"
|
|
@printf " %-18s" "pytest:"; if $(PYTEST) --version >/dev/null 2>&1; then $(PYTEST) --version | head -1; else echo "❌ Not found - run 'make dev-setup'"; fi
|
|
@printf " %-18s" "ruff:"; if $(RUFF) --version >/dev/null 2>&1; then $(RUFF) --version; else echo "❌ Not found - run 'make dev-setup'"; fi
|
|
@printf " %-18s" "mypy:"; if $(MYPY) --version >/dev/null 2>&1; then $(MYPY) --version; else echo "❌ Not found - run 'make dev-setup'"; fi
|
|
@printf " %-18s" "alembic:"; if $(ALEMBIC) --version >/dev/null 2>&1; then $(ALEMBIC) --version; else echo "❌ Not found - run 'make dev-setup'"; fi
|
|
@echo ""
|
|
@echo "Virtual environment:"
|
|
@if [ -d ".venv" ]; then \
|
|
echo " ✅ .venv exists"; \
|
|
echo " Python: $$(.venv/bin/python --version)"; \
|
|
else \
|
|
echo " ❌ .venv not found - run 'make dev-setup'"; \
|
|
fi
|
|
@echo ""
|
|
@echo "To set up missing dependencies, run: make dev-setup"
|
|
|
|
# Cleanup
|
|
clean:
|
|
@echo "🧹 Cleaning up..."
|
|
find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
|
|
find . -type d -name ".pytest_cache" -exec rm -rf {} + 2>/dev/null || true
|
|
find . -type d -name ".mypy_cache" -exec rm -rf {} + 2>/dev/null || true
|
|
find . -type f -name "*.pyc" -delete
|
|
find . -type f -name ".coverage" -delete
|
|
rm -rf htmlcov/
|
|
rm -rf dist/
|
|
rm -rf build/
|
|
rm -rf *.egg-info
|
|
@echo "✨ Cleanup complete!"
|
|
|
|
# Database migration management
|
|
db-upgrade:
|
|
@echo "⬆️ Applying all pending migrations..."
|
|
$(ALEMBIC) upgrade head
|
|
@echo "✅ Database upgraded to latest revision"
|
|
|
|
db-downgrade:
|
|
@echo "⬇️ Downgrading one migration..."
|
|
$(ALEMBIC) downgrade -1
|
|
@echo "✅ Database downgraded by one revision"
|
|
|
|
db-current:
|
|
@echo "📍 Current database revision:"
|
|
$(ALEMBIC) current -v
|
|
|
|
db-history:
|
|
@echo "📜 Migration history:"
|
|
$(ALEMBIC) history --verbose
|
|
|
|
db-migrate:
|
|
@echo "🔍 Auto-generating migration from model changes..."
|
|
@read -p "Enter migration message: " msg; \
|
|
$(ALEMBIC) revision --autogenerate -m "$$msg"
|
|
@echo "✅ Migration generated. Review and edit if needed."
|
|
|
|
db-revision:
|
|
@echo "📝 Creating empty migration file..."
|
|
@read -p "Enter migration message: " msg; \
|
|
$(ALEMBIC) revision -m "$$msg"
|
|
@echo "✅ Empty migration created"
|
|
|
|
db-heads:
|
|
@echo "🎯 Current migration heads:"
|
|
$(ALEMBIC) heads
|
|
|
|
db-clean:
|
|
@echo "🧹 Cleaning migration cache files..."
|
|
find migrations/ -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
|
|
@echo "✅ Migration cache cleaned"
|
|
|
|
# Advanced testing options
|
|
test-coverage:
|
|
@echo "📊 Running tests with coverage..."
|
|
$(PYTEST) --cov=routstr --cov-report=html --cov-report=term
|
|
@echo "Coverage report generated in htmlcov/"
|
|
|
|
test-watch:
|
|
@echo "👁️ Running tests in watch mode..."
|
|
$(PYTEST)-watch
|
|
|
|
test-parallel:
|
|
@echo "🚀 Running tests in parallel..."
|
|
$(PYTEST) -n auto -v
|
|
|
|
# CI/CD specific targets
|
|
ci-test:
|
|
@echo "🤖 Running CI test suite..."
|
|
$(PYTEST) -m "not requires_docker" --tb=short -v
|
|
|
|
ci-lint:
|
|
@echo "🤖 Running CI linting..."
|
|
$(RUFF) check . --exit-non-zero-on-fix
|
|
$(MYPY) . --no-error-summary
|
|
|
|
# Debug helpers
|
|
test-debug:
|
|
@echo "🐛 Running tests with debugging enabled..."
|
|
$(PYTEST) -vvs --tb=long --pdb-trace
|
|
|
|
test-failed:
|
|
@echo "🔄 Re-running failed tests..."
|
|
$(PYTEST) --lf -v
|
|
|
|
# Performance profiling
|
|
profile:
|
|
@echo "🔥 Running with profiling..."
|
|
$(PYTHON) -m cProfile -o profile.stats -m pytest tests/integration/test_performance_load.py::TestPerformanceBaseline -v
|
|
@echo "Profile saved to profile.stats. Use '$(PYTHON) -m pstats profile.stats' to analyze."
|
|
|
|
# Documentation
|
|
docs-build:
|
|
@echo "📚 Building documentation..."
|
|
mkdocs build
|
|
|
|
docs-serve:
|
|
@echo "📚 Serving documentation at http://localhost:8001..."
|
|
mkdocs serve -a localhost:8001
|
|
|
|
docs-deploy:
|
|
@echo "📚 Deploying documentation to GitHub Pages..."
|
|
mkdocs gh-deploy --force
|
|
|
|
docs-install:
|
|
@echo "📚 Installing documentation dependencies..."
|
|
pip install -r docs/requirements.txt
|
|
|
|
# UI build
|
|
ui-build:
|
|
@echo "🎨 Building UI for static deployment..."
|
|
./scripts/build-ui.sh
|
|
|
|
ui-build-docker:
|
|
@echo "🐳 Building UI using Docker (no Node.js installation required)..."
|
|
@echo "Building UI with environment variables from .env..."
|
|
docker build -f ui/Dockerfile.build -t routstr-ui-build --build-arg NEXT_PUBLIC_API_URL=$(NEXT_PUBLIC_API_URL) --build-arg NEXT_PUBLIC_ADMIN_API_KEY=$(NEXT_PUBLIC_ADMIN_API_KEY) .
|
|
docker run --rm -v $(PWD)/ui_out:/output routstr-ui-build cp -r /ui_out /output/
|
|
@echo "✅ UI build complete! Static files available in ui_out/"
|
|
|
|
ui-dev:
|
|
@echo "🎨 Starting UI development server..."
|
|
cd ui && (command -v pnpm >/dev/null 2>&1 && pnpm run dev || npm run dev)
|