# Use Gitea Actions for CI/CD * Status: accepted * Date: 2026-02-02 * Deciders: Billy Davies * Technical Story: Implementing continuous integration for AI/ML repositories ## Context and Problem Statement We have multiple Python and Go repositories that need automated testing, linting, and potentially Docker image builds. We need a CI/CD solution that: 1. Integrates with our self-hosted Gitea instance 2. Runs on push and pull request events 3. Supports Python (with uv) and Go workflows 4. Can build and push Docker images ## Decision Drivers * Self-hosted infrastructure (no external dependencies) * GitHub Actions compatibility (reuse existing knowledge) * Fast feedback on code quality * Consistent testing across repositories * Integration with existing tooling (uv, ruff, pytest) ## Considered Options * Gitea Actions (GitHub Actions compatible) * Drone CI * Jenkins * Woodpecker CI * External GitHub Actions (with mirror) ## Decision Outcome Chosen option: "Gitea Actions", because it provides native integration with our Gitea instance, GitHub Actions workflow compatibility, and requires no additional infrastructure. ### Positive Consequences * Native Gitea integration (no webhook configuration) * GitHub Actions syntax compatibility (easy migration) * Self-hosted runners for security and speed * No external service dependencies * Reuse of GitHub Actions marketplace (with caveats) ### Negative Consequences * Gitea Actions runner requires maintenance * Some GitHub Actions not compatible (use `https://gitea.com/actions/` equivalents) * Less mature than GitHub Actions ecosystem ## Repositories with CI | Repository | Language | CI Scope | |------------|----------|----------| | handler-base | Python | Lint (ruff), Test (pytest), Type check | | voice-assistant | Python | Lint, Test | | chat-handler | Python | Lint, Test | | pipeline-bridge | Python | Lint, Test | | companions-frontend | Go | Lint (golangci-lint), Test, Build | | mlflow | Python | Lint, Test | | tts-module | Python | Lint, Test, Docker build+push | | stt-module | Python | Lint, Test, Docker build+push | ## Workflow Patterns ### Python Repositories ```yaml name: CI on: push: branches: [main] pull_request: branches: [main] jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v5 - run: uv sync --frozen - run: uv run ruff check . - run: uv run ruff format --check . test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v5 - run: uv sync --frozen - run: uv run pytest --cov ``` ### Docker Build (Optional) Repositories that need container images can add a docker job: ```yaml docker: needs: [lint, test] if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - uses: docker/build-push-action@v5 with: push: true tags: ghcr.io/${{ github.repository }}:latest ``` ## Runner Configuration Gitea Actions runners are deployed in the Kubernetes cluster: ```yaml # Runner deployed via Helm helm repo add gitea-actions-runner https://gitea.com/gitea/helm-charts helm install runner gitea-actions-runner/actions-runner \ --set runner.token= \ --set runner.url=https://git.daviestechlabs.io ``` ## Migration from GitHub For repositories with existing `.github/workflows/`: 1. Copy to `.gitea/workflows/` (Gitea also supports `.github/workflows/`) 2. Replace GitHub-specific actions with Gitea equivalents: - `actions/checkout@v4` → Works as-is (proxied) - `codecov/codecov-action` → May need self-hosted alternative 3. Update secrets references if needed ## Links * [Gitea Actions Documentation](https://docs.gitea.com/usage/actions/overview) * [Gitea Actions Marketplace](https://gitea.com/actions) * [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) - uv setup action * Related: [ADR-0012](0012-use-uv-for-python-development.md) - uv for Python development