Implement FastAPI webhook receiver for Gitea issue assignment events with HMAC SHA256 signature verification and event routing. Implementation details: - FastAPI application with /webhook/gitea POST endpoint - HMAC SHA256 signature verification in security.py - Event routing for assigned, unassigned, closed actions - Comprehensive logging for all webhook events - Health check endpoint at /health - Docker containerization with health checks - 91% test coverage (exceeds 85% requirement) TDD workflow followed: - Wrote 16 tests first (RED phase) - Implemented features to pass tests (GREEN phase) - All tests passing with 91% coverage - Type checking with mypy: success - Linting with ruff: success Files created: - apps/coordinator/src/main.py - FastAPI application - apps/coordinator/src/webhook.py - Webhook handlers - apps/coordinator/src/security.py - HMAC verification - apps/coordinator/src/config.py - Configuration management - apps/coordinator/tests/ - Comprehensive test suite - apps/coordinator/Dockerfile - Production container - apps/coordinator/pyproject.toml - Python project config Configuration: - Updated .env.example with GITEA_WEBHOOK_SECRET - Updated docker-compose.yml with coordinator service Testing: - 16 unit and integration tests - Security tests for signature verification - Event handler tests for all supported actions - Health check endpoint tests - All tests passing with 91% coverage This unblocks issue #158 (issue parser). Fixes #157 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
81 lines
1.9 KiB
YAML
81 lines
1.9 KiB
YAML
services:
|
|
postgres:
|
|
build:
|
|
context: ./postgres
|
|
dockerfile: Dockerfile
|
|
container_name: mosaic-postgres
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: ${POSTGRES_USER:-mosaic}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-mosaic_dev_password}
|
|
POSTGRES_DB: ${POSTGRES_DB:-mosaic}
|
|
ports:
|
|
- "${POSTGRES_PORT:-5432}:5432"
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-mosaic} -d ${POSTGRES_DB:-mosaic}"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 30s
|
|
networks:
|
|
- mosaic-network
|
|
|
|
valkey:
|
|
image: valkey/valkey:8-alpine
|
|
container_name: mosaic-valkey
|
|
restart: unless-stopped
|
|
ports:
|
|
- "${VALKEY_PORT:-6379}:6379"
|
|
volumes:
|
|
- valkey_data:/data
|
|
healthcheck:
|
|
test: ["CMD", "valkey-cli", "ping"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 10s
|
|
networks:
|
|
- mosaic-network
|
|
|
|
coordinator:
|
|
build:
|
|
context: ../apps/coordinator
|
|
dockerfile: Dockerfile
|
|
container_name: mosaic-coordinator
|
|
restart: unless-stopped
|
|
environment:
|
|
GITEA_WEBHOOK_SECRET: ${GITEA_WEBHOOK_SECRET}
|
|
GITEA_URL: ${GITEA_URL:-https://git.mosaicstack.dev}
|
|
LOG_LEVEL: ${LOG_LEVEL:-info}
|
|
HOST: 0.0.0.0
|
|
PORT: 8000
|
|
ports:
|
|
- "8000:8000"
|
|
healthcheck:
|
|
test:
|
|
[
|
|
"CMD",
|
|
"python",
|
|
"-c",
|
|
"import urllib.request; urllib.request.urlopen('http://localhost:8000/health')",
|
|
]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 5s
|
|
networks:
|
|
- mosaic-network
|
|
|
|
volumes:
|
|
postgres_data:
|
|
name: mosaic-postgres-data
|
|
valkey_data:
|
|
name: mosaic-valkey-data
|
|
|
|
networks:
|
|
mosaic-network:
|
|
name: mosaic-network
|
|
driver: bridge
|