diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..65c7806 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,43 @@ +# Git +.git +.gitignore + +# Python +__pycache__ +*.py[cod] +*$py.class +*.so +.Python +.venv +venv +ENV +env + +# Testing +.pytest_cache +.coverage +htmlcov +tests/ + +# IDE +.idea +.vscode +*.swp +*.swo + +# Logs +logs/ +*.log + +# Environment +.env +.env.local +.env.*.local + +# Development files +*.md +!README.md +requirements-dev.txt +implementation-plan.md +fastapi-best-practices.md +wakeup.sh diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..8ae16c5 --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,46 @@ +name: Build and Push + +on: + push: + tags: + - 'v*' + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Create Gitea Release + run: | + curl -sf -X POST \ + -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + -H "Content-Type: application/json" \ + -d '{"tag_name": "${{ github.ref_name }}", "name": "Release ${{ github.ref_name }}", "body": "Automated release for ${{ github.ref_name }}"}' \ + "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases" + + build: + runs-on: ubuntu-latest + needs: release + steps: + - uses: actions/checkout@v4 + + - name: Login to Gitea Registry + uses: docker/login-action@v3 + with: + registry: git.schweitz.internal + username: ${{ secrets.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: | + git.schweitz.internal/jpmschweitzer/webber:latest + git.schweitz.internal/jpmschweitzer/webber:${{ github.ref_name }} + + - name: Trigger Watchtower update + if: success() + run: | + curl -sf -H "Authorization: Bearer ${{ secrets.WATCHTOWER_TOKEN }}" \ + http://watchtower:8080/v1/update diff --git a/AGENTS.md b/AGENTS.md index 7c07af0..7ed0e7a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -48,6 +48,7 @@ When changes are ready for deployment: 5. **CI/CD triggers automatically**: - Gitea CI builds Docker image on new version tag (starts with "v") - Watchtower pulls and deploys to production + - Verify deployment: `curl http://192.168.86.149:8086/health` --- diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..1bc2033 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,26 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.1.0] - 2026-01-09 + +### Added +- Initial FastAPI boilerplate setup +- Domain-based project structure (src/domains/, src/shared/) +- BaseController pattern with lazy router instantiation +- Pydantic Settings configuration with env file support +- Logger decorator with temporal benchmarking and trace IDs +- UserProvider singleton for request-scoped context +- Custom exception hierarchy +- Health endpoints (/, /health) +- Placeholder domains for agents (explore, plan, task) +- Placeholder domains for tools (file, shell, search) +- Placeholder domain for auth (tatlock integration) +- CI/CD workflow for Gitea with Docker build and Watchtower deployment +- Dockerfile for containerized deployment +- CVE-checked dependencies (2026-01-09) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..15c5131 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM python:3.12-slim + +WORKDIR /app + +# Install system dependencies (curl for healthcheck) +RUN apt-get update && apt-get install -y \ + curl \ + && rm -rf /var/lib/apt/lists/* + +# Install Python dependencies +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# Copy application +COPY pyproject.toml . +COPY src/ ./src/ + +ENV PYTHONPATH=/app + +EXPOSE 8086 + +CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8086", "--workers", "1"]