Modernized build tooling

This commit is contained in:
2025-08-01 05:00:24 +00:00
committed by Your Name
parent 8a93f794d6
commit f7a5d26c41
71 changed files with 6685 additions and 813 deletions
+124
View File
@@ -0,0 +1,124 @@
# Development container for Python 3.13 Boilerplate project with Claude Code + MCP servers
FROM python:3.13-slim
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
# Essential build tools
build-essential \
gcc \
g++ \
make \
# Development utilities
curl \
wget \
git \
vim \
nano \
jq \
tree \
htop \
unzip \
ca-certificates \
# Shell enhancements
zsh \
# Networking tools
net-tools \
iputils-ping \
# Process management
procps \
# For MCP servers
gnupg \
lsb-release \
software-properties-common \
# Clean up
&& rm -rf /var/lib/apt/lists/*
# Install Node.js 20 (required for many MCP servers)
RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
&& apt-get update \
&& apt-get install -y nodejs \
&& rm -rf /var/lib/apt/lists/*
# Install Go 1.22+ (for building Forgejo MCP if needed)
RUN curl -fsSL https://go.dev/dl/go1.22.10.linux-amd64.tar.gz | tar -xzC /usr/local \
&& ln -s /usr/local/go/bin/go /usr/local/bin/go \
&& ln -s /usr/local/go/bin/gofmt /usr/local/bin/gofmt
# Install Claude Code CLI
RUN curl -fsSL https://raw.githubusercontent.com/anthropics/claude-code/main/install.sh | sh
# Install uv package manager
RUN pip install --no-cache-dir uv>=0.8.0
# Install development tools globally
RUN pip install --no-cache-dir \
ruff>=0.4.0 \
pyright>=1.1.400 \
pre-commit>=3.8.0 \
nox>=2025.4.22
# Install MCP servers globally
RUN npm install -g \
test-runner-mcp \
@crunchloop/mcp-devcontainers \
kubernetes-mcp-server \
@opentofu/opentofu-mcp-server
# Install Python-based MCP servers
RUN pip install --no-cache-dir \
ruff-mcp-server \
uvx
# Install uvx-based MCP servers
RUN uvx install uv-mcp
# Create non-root user
RUN groupadd --gid 1000 vscode \
&& useradd --uid 1000 --gid vscode --shell /bin/bash --create-home vscode \
&& echo "vscode ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# Set up user environment
USER vscode
WORKDIR /workspaces/boilerplate
# Create directories for MCP server configurations and logs
RUN mkdir -p ~/.config/claude-code \
&& mkdir -p ~/.local/bin \
&& mkdir -p ~/.local/share/mcp-logs
# Configure git for the user
RUN git config --global init.defaultBranch main \
&& git config --global pull.rebase false \
&& git config --global user.name "Dev Container User" \
&& git config --global user.email "dev@example.com"
# Install Oh My Zsh for better shell experience
RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
# Set default shell to zsh
ENV SHELL=/bin/zsh
# Create workspace directories
RUN mkdir -p /workspaces/boilerplate/.venv \
&& mkdir -p /tmp/uv-cache \
&& chown -R vscode:vscode /workspaces/boilerplate \
&& chown -R vscode:vscode /tmp/uv-cache
# Set environment variables
ENV PYTHONPATH=/workspaces/boilerplate/src
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV PIP_NO_CACHE_DIR=1
ENV UV_CACHE_DIR=/tmp/uv-cache
# MCP server environment variables
ENV PATH=$PATH:/usr/local/go/bin:~/.local/bin
ENV NODE_PATH=/usr/local/lib/node_modules
ENV MCP_LOG_DIR=/home/vscode/.local/share/mcp-logs
# Set working directory
WORKDIR /workspaces/boilerplate
# Keep container running
CMD ["sleep", "infinity"]
+74
View File
@@ -0,0 +1,74 @@
# Python 3.13 Boilerplate Development Environment
# Activate virtual environment automatically
if [ -f "/workspaces/boilerplate/.venv/bin/activate" ]; then
source /workspaces/boilerplate/.venv/bin/activate
fi
# Useful aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
alias ..='cd ..'
alias ...='cd ../..'
# Development shortcuts
alias dev-test='nox -s behave'
alias dev-lint='nox -s lint'
alias dev-format='nox -s format'
alias dev-type='nox -s typecheck'
alias dev-docs='nox -s serve_docs'
alias dev-all='nox'
# Docker shortcuts
alias d='docker'
alias dc='docker-compose'
alias k='kubectl'
# Git shortcuts
alias gs='git status'
alias ga='git add'
alias gc='git commit'
alias gp='git push'
alias gl='git pull'
alias gco='git checkout'
alias gb='git branch'
# Python shortcuts
alias py='python'
alias pip='uv pip'
alias venv='uv venv'
# Project-specific commands
alias run-cli='python -m boilerplate'
alias test-quick='behave -q'
alias build-docker='docker build -t boilerplate:dev .'
# Claude Code and MCP shortcuts
alias claude='claude-code'
alias mcp-status='claude-code --list-servers'
alias mcp-logs='tail -f ~/.local/share/mcp-logs/*.log'
# Set up completion for kubectl if available
if command -v kubectl &> /dev/null; then
source <(kubectl completion bash)
fi
# Set up completion for helm if available
if command -v helm &> /dev/null; then
source <(helm completion bash)
fi
# Colorful prompt
export PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
# Environment info
echo "🐍 Python $(python --version)"
echo "📦 uv $(uv --version)"
echo "🦀 ruff $(ruff --version)"
echo "🔍 pyright $(pyright --version)"
echo "🧪 behave $(behave --version)"
echo ""
echo "📁 Working directory: $(pwd)"
echo "🌿 Git branch: $(git branch --show-current 2>/dev/null || echo 'not initialized')"
echo ""
+71
View File
@@ -0,0 +1,71 @@
{
"mcpServers": {
"forgejo": {
"command": "forgejo-mcp",
"args": ["-t", "stdio", "--host", "https://localhost:3000"],
"env": {
"GITEA_ACCESS_TOKEN": "${FORGEJO_PAT:-your-forgejo-token-here}"
}
},
"tests": {
"command": "node",
"args": ["/usr/local/lib/node_modules/test-runner-mcp/build/index.js"]
},
"ruff": {
"command": "ruff-mcp-server"
},
"uv": {
"command": "uvx",
"args": ["uv-mcp"]
},
"devcontainers": {
"command": "npx",
"args": ["-y", "@crunchloop/mcp-devcontainers"]
},
"kubernetes": {
"command": "npx",
"args": ["kubernetes-mcp-server@latest"],
"env": {
"KUBECONFIG": "${KUBECONFIG:-~/.kube/config}"
}
},
"prometheus": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "PROMETHEUS_URL",
"ghcr.io/pab1it0/prometheus-mcp-server:latest"
],
"env": {
"PROMETHEUS_URL": "${PROMETHEUS_URL:-http://localhost:9090}"
}
},
"grafana": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "GRAFANA_API_TOKEN",
"ghcr.io/grafana/mcp-grafana:latest"
],
"env": {
"GRAFANA_API_TOKEN": "${GRAFANA_API_TOKEN:-your-grafana-token-here}"
}
},
"tofu": {
"transport": "sse",
"endpoint": "https://mcp.opentofu.org/sse"
}
},
"globalShortcuts": {
"claude": "ctrl+shift+c"
},
"editor": {
"wordWrap": true,
"fontSize": 14,
"fontFamily": "JetBrains Mono, 'Courier New', monospace"
},
"ui": {
"theme": "dark",
"sidebarWidth": 300
}
}
+154
View File
@@ -0,0 +1,154 @@
{
"name": "Python 3.13 Boilerplate Dev Environment",
"dockerFile": "Dockerfile",
"context": "..",
// Configure tool-specific properties
"customizations": {
"vscode": {
"settings": {
"python.defaultInterpreterPath": "/usr/local/bin/python",
"python.linting.enabled": true,
"python.linting.ruffEnabled": true,
"python.linting.pylintEnabled": false,
"python.linting.flake8Enabled": false,
"python.formatting.provider": "none",
"python.formatting.blackProvider": "none",
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true,
"source.fixAll": true
}
},
"python.testing.pytestEnabled": false,
"python.testing.unittestEnabled": false,
"behave.language": "gherkin",
"files.associations": {
"*.feature": "gherkin"
},
"yaml.schemas": {
"https://json.schemastore.org/github-workflow.json": "/.forgejo/workflows/*.yml",
"https://json.schemastore.org/helmfile.json": "/k8s/values.yaml"
},
"terminal.integrated.defaultProfile.linux": "bash",
"terminal.integrated.profiles.linux": {
"bash": {
"path": "/bin/bash",
"args": ["-l"]
}
}
},
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"charliermarsh.ruff",
"ms-vscode.vscode-json",
"redhat.vscode-yaml",
"ms-kubernetes-tools.vscode-kubernetes-tools",
"ms-vscode-remote.remote-containers",
"alexkrechik.cucumberautocomplete",
"stevejpurves.cucumber",
"wholroyd.jinja",
"ms-vscode.makefile-tools",
"davidanson.vscode-markdownlint",
"yzhang.markdown-all-in-one"
]
}
},
// Use 'postCreateCommand' to run commands after the container is created
"postCreateCommand": ".devcontainer/post-create.sh",
// Use 'postStartCommand' to run commands after the container starts
"postStartCommand": "echo 'Welcome to your Python 3.13 development environment! 🚀'",
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root
"remoteUser": "vscode",
// Features to add to the dev container
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
"installZsh": true,
"configureZshAsDefaultShell": true,
"installOhMyZsh": true,
"upgradePackages": true,
"username": "vscode",
"userUid": "1000",
"userGid": "1000"
},
"ghcr.io/devcontainers/features/git:1": {
"ppa": true,
"version": "latest"
},
"ghcr.io/devcontainers/features/github-cli:1": {
"installDirectlyFromGitHubRelease": true,
"version": "latest"
},
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"version": "latest",
"enableNonRootDocker": "true",
"moby": "true"
},
"ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {
"version": "latest",
"helm": "latest",
"minikube": "none"
}
},
// Configure container environment
"containerEnv": {
"PYTHONPATH": "/workspaces/boilerplate/src",
"PYTHONDONTWRITEBYTECODE": "1",
"PYTHONUNBUFFERED": "1",
"PIP_NO_CACHE_DIR": "1",
"UV_CACHE_DIR": "/tmp/uv-cache",
"MCP_LOG_DIR": "/home/vscode/.local/share/mcp-logs",
"NODE_PATH": "/usr/local/lib/node_modules"
},
// Mounts
"mounts": [
"source=${localWorkspaceFolder}/.devcontainer/bashrc-append.sh,target=/tmp/bashrc-append.sh,type=bind,consistency=cached",
"source=boilerplate-uv-cache,target=/tmp/uv-cache,type=volume",
"source=boilerplate-mcp-cache,target=/home/vscode/.local/share/mcp-logs,type=volume"
],
// Port forwarding
"forwardPorts": [8000, 8080, 3000, 9090, 3001],
"portsAttributes": {
"8000": {
"label": "Application Server",
"onAutoForward": "notify"
},
"8080": {
"label": "Development Server",
"onAutoForward": "silent"
},
"3000": {
"label": "MkDocs Development Server",
"onAutoForward": "notify"
},
"9090": {
"label": "Prometheus Server",
"onAutoForward": "silent"
},
"3001": {
"label": "Forgejo/Gitea Server",
"onAutoForward": "silent"
}
},
// Lifecycle scripts
"initializeCommand": "echo 'Initializing Python 3.13 Boilerplate Dev Environment...'",
"onCreateCommand": "echo 'Creating development environment...'",
// Resource limits (increased for MCP servers and Claude Code)
"hostRequirements": {
"cpus": 4,
"memory": "8gb",
"storage": "16gb"
}
}
+68
View File
@@ -0,0 +1,68 @@
#!/bin/bash
set -e
echo "🚀 Setting up Python 3.13 Boilerplate development environment..."
# Ensure we're in the right directory
cd /workspaces/boilerplate
# Create virtual environment with uv
echo "📦 Creating virtual environment..."
uv venv .venv
source .venv/bin/activate
# Install project dependencies
echo "📥 Installing dependencies..."
uv pip install -e .[dev]
# Install pre-commit hooks
echo "🪝 Setting up pre-commit hooks..."
pre-commit install --install-hooks
# Create reports directory for test outputs
mkdir -p reports
# Set up shell environment
echo "🐚 Configuring shell environment..."
cat /tmp/bashrc-append.sh >> ~/.bashrc
cat /tmp/bashrc-append.sh >> ~/.zshrc
# Initialize git if not already done
if [ ! -d .git ]; then
echo "🔧 Initializing git repository..."
git init
git add .
git commit -m "Initial commit from devcontainer setup"
fi
# Run initial checks to ensure everything works
echo "✅ Running initial health checks..."
ruff --version
pyright --version
behave --version
# Try a quick test
echo "🧪 Running a quick test..."
python -m boilerplate --version || echo "⚠️ CLI not ready yet (normal for initial setup)"
# Set up MCP servers
echo "🔧 Setting up Claude Code MCP servers..."
bash /workspaces/boilerplate/.devcontainer/setup-mcp.sh
echo ""
echo "🎉 Development environment setup complete!"
echo ""
echo "Quick start commands:"
echo " nox -s behave # Run BDD tests"
echo " nox -s lint # Run linting"
echo " nox -s format # Format code"
echo " nox -s docs # Build documentation"
echo ""
echo "Claude Code + MCP commands:"
echo " claude # Start Claude Code with MCP servers"
echo " mcp-status # Check MCP server status"
echo " mcp-logs # View MCP server logs"
echo ""
echo "🔧 Configure tokens in ~/.local/share/mcp-env-template for full MCP functionality"
echo ""
echo "Happy coding! 🐍✨🤖"
+105
View File
@@ -0,0 +1,105 @@
#!/bin/bash
set -e
echo "🔧 Setting up Claude Code MCP servers..."
# Create necessary directories
mkdir -p ~/.config/claude-code
mkdir -p ~/.local/bin
mkdir -p ~/.local/share/mcp-logs
# Copy Claude Code configuration
cp /workspaces/boilerplate/.devcontainer/claude-code-config.json ~/.config/claude-code/config.json
# Install or update Forgejo MCP server if Go is available
if command -v go &> /dev/null; then
echo "📦 Installing Forgejo MCP server..."
if [ ! -f ~/.local/bin/forgejo-mcp ]; then
# Clone and build Forgejo MCP (fallback if binary not available)
cd /tmp
git clone https://forgejo.org/forgejo/forgejo-mcp.git 2>/dev/null || echo "⚠️ Forgejo MCP repository not available, skipping..."
if [ -d forgejo-mcp ]; then
cd forgejo-mcp
make build 2>/dev/null && cp forgejo-mcp ~/.local/bin/ || echo "⚠️ Could not build Forgejo MCP"
cd /workspaces/boilerplate
rm -rf /tmp/forgejo-mcp
fi
fi
fi
# Ensure MCP servers are accessible
echo "🔍 Checking MCP server availability..."
# Test Node.js based servers
echo " - test-runner-mcp: $(npm list -g test-runner-mcp 2>/dev/null | grep test-runner-mcp || echo 'not found')"
echo " - devcontainers: $(npm list -g @crunchloop/mcp-devcontainers 2>/dev/null | grep mcp-devcontainers || echo 'not found')"
echo " - kubernetes: $(npm list -g kubernetes-mcp-server 2>/dev/null | grep kubernetes-mcp-server || echo 'not found')"
# Test Python-based servers
echo " - ruff: $(python -c 'import ruff_mcp_server; print("available")' 2>/dev/null || echo 'not found')"
# Test uvx-based servers
echo " - uv-mcp: $(uvx --help 2>/dev/null | grep -q 'uv-mcp' && echo 'available' || echo 'not found')"
# Create wrapper scripts for containerized MCP servers
echo "📝 Creating wrapper scripts..."
# Prometheus MCP wrapper
cat > ~/.local/bin/prometheus-mcp << 'EOF'
#!/bin/bash
exec docker run -i --rm \
-e PROMETHEUS_URL="${PROMETHEUS_URL:-http://localhost:9090}" \
ghcr.io/pab1it0/prometheus-mcp-server:latest "$@"
EOF
chmod +x ~/.local/bin/prometheus-mcp
# Grafana MCP wrapper
cat > ~/.local/bin/grafana-mcp << 'EOF'
#!/bin/bash
exec docker run -i --rm \
-e GRAFANA_API_TOKEN="${GRAFANA_API_TOKEN}" \
ghcr.io/grafana/mcp-grafana:latest "$@"
EOF
chmod +x ~/.local/bin/grafana-mcp
# Create environment template file
cat > ~/.local/share/mcp-env-template << 'EOF'
# MCP Server Environment Variables
# Copy this to ~/.bashrc or ~/.zshrc and customize
# Forgejo/Gitea Configuration
export FORGEJO_PAT="your-forgejo-personal-access-token"
export GITEA_ACCESS_TOKEN="$FORGEJO_PAT"
# Prometheus Configuration
export PROMETHEUS_URL="http://localhost:9090"
# Grafana Configuration
export GRAFANA_API_TOKEN="your-grafana-api-token"
# Kubernetes Configuration
export KUBECONFIG="~/.kube/config"
# Docker Configuration (if using remote Docker)
# export DOCKER_HOST="tcp://docker.example.com:2376"
EOF
echo ""
echo "✅ MCP setup complete!"
echo ""
echo "📋 Next steps:"
echo "1. Copy environment variables from ~/.local/share/mcp-env-template to your shell config"
echo "2. Configure your tokens and endpoints"
echo "3. Run 'claude-code' to start with MCP servers enabled"
echo ""
echo "🔧 Available MCP servers:"
echo " - forgejo: Git repository management"
echo " - tests: Test runner with uv + ruff"
echo " - ruff: Python linting and formatting"
echo " - uv: Python package management"
echo " - devcontainers: Development container management"
echo " - kubernetes: Kubernetes cluster operations"
echo " - prometheus: Metrics and monitoring queries"
echo " - grafana: Dashboard and alerting management"
echo " - tofu: Infrastructure as Code with OpenTofu"
echo ""