Skip to content

feat: implement dynamic capability detection and generic system archi… #22

feat: implement dynamic capability detection and generic system archi…

feat: implement dynamic capability detection and generic system archi… #22

Workflow file for this run

name: CI
on:
pull_request:
branches: [ main, master, develop ]
push:
branches: [ main, master, develop ]
env:
PYTHON_VERSION: "3.13"
jobs:
lint:
name: Lint Code
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
version: "latest"
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install dependencies and package
run: |
uv sync --dev
- name: Run Ruff linter
run: |
uv run ruff check src/ tests/
- name: Run Ruff formatter check
run: |
uv run ruff format --check src/ tests/
type-check:
name: Type Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
version: "latest"
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install dependencies and package
run: |
uv sync --dev
- name: Run mypy
run: |
uv run mypy src/ --ignore-missing-imports --check-untyped-defs || true
security-check:
name: Security Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
version: "latest"
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install security tools and package
run: |
uv sync --dev
- name: Run Bandit security linter
run: |
uv run bandit -r src/ -ll
- name: Check for known vulnerabilities
run: |
uv run pip-audit || true
- name: Check for hardcoded secrets
run: |
# Check for common patterns that might indicate credentials
! grep -rE "(password|passwd|pwd|secret|api_key|apikey|token|credential)\s*=\s*[\"'][^\"']+[\"']" src/ --include="*.py" || (echo "Potential hardcoded secrets found!" && exit 1)
! grep -rE "([0-9]{1,3}\.){3}[0-9]{1,3}" src/ --include="*.py" || echo "Warning: IP addresses found in code"
! grep -rE "(BEGIN (RSA|DSA|EC|OPENSSH) PRIVATE KEY|BEGIN CERTIFICATE)" src/ || (echo "Private keys or certificates found!" && exit 1)
test:
name: Run Tests
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
version: "latest"
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies and package
run: |
uv sync --dev
- name: Run tests
run: |
# Run tests if they exist, otherwise skip
if [ -d "tests" ]; then
uv run python -m pytest tests/ -v --cov=src/loxone_mcp --cov-report=term-missing
else
echo "No tests directory found, skipping tests"
fi
- name: Test MCP server startup
run: |
# Just check if the server can be imported without errors
uv run python -c "from loxone_mcp import mcp; print('Server module imports successfully')"
validate-mcp:
name: Validate MCP Implementation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
version: "latest"
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install dependencies and package
run: |
uv sync --dev
- name: Validate MCP server
run: |
# Check if server exposes required MCP methods
uv run python << 'EOF'
import inspect
from loxone_mcp.server import mcp
import loxone_mcp.server as server_module
print('Checking MCP server implementation...')
tools = []
prompts = []
resources = []
# Check for decorated functions by examining source code
for name, obj in inspect.getmembers(server_module):
if inspect.isfunction(obj) and not name.startswith('_'):
try:
source = inspect.getsource(obj)
if '@mcp.tool(' in source or '@mcp.tool()' in source:
tools.append(name)
elif '@mcp.prompt(' in source:
prompts.append(name)
elif '@mcp.resource(' in source:
resources.append(name)
except (OSError, TypeError):
continue
print(f'Found {len(tools)} tools: {tools}')
print(f'Found {len(prompts)} prompts: {prompts}')
print(f'Found {len(resources)} resources: {resources}')
# Basic validation
assert len(tools) > 0, 'No MCP tools found!'
assert len(prompts) > 0, 'No MCP prompts found!'
print('✅ MCP server validation passed!')
EOF
build:
name: Build Package
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
version: "latest"
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Build package
run: |
uv build
- name: Check package
run: |
uv add --dev twine
uv run twine check dist/*
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist/
check-dependencies:
name: Check Dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
version: "latest"
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Check for dependency conflicts
run: |
uv sync --dev
uv run python -c "import pkg_resources; print('Dependencies OK')" || true
- name: Generate dependency tree
run: |
uv add --dev pipdeptree
uv run pipdeptree