name: ci on: push: branches: [main] pull_request: branches: [main] env: REGISTRY: git.tielogic.xyz IMAGE_PREFIX: git.tielogic.xyz/adriano/cerbero-mcp jobs: lint: name: ruff lint runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: Install uv run: pipx install uv || pip install --user uv - name: Install deps run: uv sync --frozen --group dev - name: Ruff check run: uv run ruff check services/ typecheck: name: mypy mcp_common runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: Install uv run: pipx install uv || pip install --user uv - name: Install deps run: uv sync --frozen --group dev - name: Mypy on mcp_common (gating) run: uv run mypy services/common/src/mcp_common - name: Mypy on services (warn-only) run: uv run mypy services/ || true test: name: pytest runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: Install uv run: pipx install uv || pip install --user uv - name: Install deps run: uv sync --frozen --group dev - name: Pytest full suite run: uv run pytest services/ --tb=short validate-config: name: validate compose + Caddyfile runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: Validate dev compose run: docker compose -f docker-compose.yml config -q - name: Validate prod compose run: docker compose -f docker-compose.prod.yml config -q env: ACME_EMAIL: test@example.com WRITE_ALLOWLIST: "127.0.0.1/32" - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build gateway image (local, no push) uses: docker/build-push-action@v6 with: context: ./gateway file: gateway/Dockerfile tags: cerbero-gateway:validate load: true - name: Validate Caddyfile syntax run: | docker run --rm \ -v "$PWD/gateway/Caddyfile:/etc/caddy/Caddyfile:ro" \ -e ACME_EMAIL=test@example.com \ -e WRITE_ALLOWLIST="127.0.0.1/32" \ cerbero-gateway:validate \ caddy validate --config /etc/caddy/Caddyfile build-and-push: name: build & push to registry runs-on: ubuntu-22.04 needs: [lint, test, validate-config] if: github.event_name == 'push' && github.ref == 'refs/heads/main' permissions: packages: write steps: - uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to Gitea registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ gitea.actor }} password: ${{ secrets.GITEA_TOKEN }} - name: Compute short SHA id: meta run: echo "sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - name: Build base image (load to local daemon) uses: docker/build-push-action@v6 with: context: . file: docker/base.Dockerfile tags: cerbero-base:latest load: true cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/buildcache:base cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/buildcache:base,mode=max - name: Build & push gateway uses: docker/build-push-action@v6 with: context: ./gateway file: gateway/Dockerfile push: true tags: | ${{ env.IMAGE_PREFIX }}/gateway:latest ${{ env.IMAGE_PREFIX }}/gateway:sha-${{ steps.meta.outputs.sha }} cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/buildcache:gateway cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/buildcache:gateway,mode=max - name: Build & push mcp-deribit uses: docker/build-push-action@v6 with: context: . file: docker/mcp-deribit.Dockerfile build-args: BASE_TAG=latest push: true tags: | ${{ env.IMAGE_PREFIX }}/mcp-deribit:latest ${{ env.IMAGE_PREFIX }}/mcp-deribit:sha-${{ steps.meta.outputs.sha }} cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/buildcache:mcp-deribit cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/buildcache:mcp-deribit,mode=max - name: Build & push mcp-bybit uses: docker/build-push-action@v6 with: context: . file: docker/mcp-bybit.Dockerfile build-args: BASE_TAG=latest push: true tags: | ${{ env.IMAGE_PREFIX }}/mcp-bybit:latest ${{ env.IMAGE_PREFIX }}/mcp-bybit:sha-${{ steps.meta.outputs.sha }} cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/buildcache:mcp-bybit cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/buildcache:mcp-bybit,mode=max - name: Build & push mcp-hyperliquid uses: docker/build-push-action@v6 with: context: . file: docker/mcp-hyperliquid.Dockerfile build-args: BASE_TAG=latest push: true tags: | ${{ env.IMAGE_PREFIX }}/mcp-hyperliquid:latest ${{ env.IMAGE_PREFIX }}/mcp-hyperliquid:sha-${{ steps.meta.outputs.sha }} cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/buildcache:mcp-hyperliquid cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/buildcache:mcp-hyperliquid,mode=max - name: Build & push mcp-alpaca uses: docker/build-push-action@v6 with: context: . file: docker/mcp-alpaca.Dockerfile build-args: BASE_TAG=latest push: true tags: | ${{ env.IMAGE_PREFIX }}/mcp-alpaca:latest ${{ env.IMAGE_PREFIX }}/mcp-alpaca:sha-${{ steps.meta.outputs.sha }} cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/buildcache:mcp-alpaca cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/buildcache:mcp-alpaca,mode=max - name: Build & push mcp-macro uses: docker/build-push-action@v6 with: context: . file: docker/mcp-macro.Dockerfile build-args: BASE_TAG=latest push: true tags: | ${{ env.IMAGE_PREFIX }}/mcp-macro:latest ${{ env.IMAGE_PREFIX }}/mcp-macro:sha-${{ steps.meta.outputs.sha }} cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/buildcache:mcp-macro cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/buildcache:mcp-macro,mode=max - name: Build & push mcp-sentiment uses: docker/build-push-action@v6 with: context: . file: docker/mcp-sentiment.Dockerfile build-args: BASE_TAG=latest push: true tags: | ${{ env.IMAGE_PREFIX }}/mcp-sentiment:latest ${{ env.IMAGE_PREFIX }}/mcp-sentiment:sha-${{ steps.meta.outputs.sha }} cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/buildcache:mcp-sentiment cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/buildcache:mcp-sentiment,mode=max