name: docker on: # Test on every branch push; registry push is gated per-step to main/dev. push: branches: - '**' pull_request: branches: - main - dev jobs: # --------------------------------------------------------------------------- # 1. Lint: ruff + black + mypy. # --------------------------------------------------------------------------- lint: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.12" - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements-dev.txt - name: Run lint run: | ruff check src tests ruff format --check src tests black --check src tests mypy src # --------------------------------------------------------------------------- # 2. Test: pytest with coverage gate. # --------------------------------------------------------------------------- test: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.12" - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements-dev.txt - name: Run tests run: pytest --cov=aegis_gitea_mcp --cov-report=term-missing --cov-fail-under=80 # --------------------------------------------------------------------------- # 3. Build the Docker image, smoke-test it, push to Gitea (push events to # main/dev only), then clean up so nothing lingers on the self-hosted # runner. # --------------------------------------------------------------------------- docker: needs: [lint, test] runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Compute image name & tags id: meta shell: bash run: | IMAGE="git.hiddenden.cafe/${GITHUB_REPOSITORY,,}" echo "image=${IMAGE}" >> "$GITHUB_OUTPUT" echo "sha_tag=${IMAGE}:sha-${GITHUB_SHA::12}" >> "$GITHUB_OUTPUT" if [ "${GITHUB_REF_NAME}" = "main" ]; then # Production: stable :latest + :main echo "branch_tags=${IMAGE}:latest ${IMAGE}:main" >> "$GITHUB_OUTPUT" else # dev (and any other branch): tag with the branch name echo "branch_tags=${IMAGE}:${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT" fi - name: Build image shell: bash run: docker build -f docker/Dockerfile -t "${{ steps.meta.outputs.sha_tag }}" . - name: Smoke-test image shell: bash run: | docker run --rm --entrypoint python "${{ steps.meta.outputs.sha_tag }}" \ -c "import aegis_gitea_mcp" echo "Image imports cleanly." - name: Log in to Gitea Container Registry if: github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'dev') uses: docker/login-action@v3 with: registry: git.hiddenden.cafe username: ${{ github.actor }} # PAT with write:package scope, stored as the REGISTRY_TOKEN secret. # The auto-provided GITEA_TOKEN lacks package-write permission on # this instance, so we use a dedicated token here. password: ${{ secrets.REGISTRY_TOKEN }} - name: Tag & push if: github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'dev') shell: bash run: | for tag in ${{ steps.meta.outputs.branch_tags }} ${{ steps.meta.outputs.sha_tag }}; do docker tag "${{ steps.meta.outputs.sha_tag }}" "$tag" docker push "$tag" echo "Pushed $tag" done # Always runs — removes exactly what this run created, even on failure. # Scoped on purpose: if the runner shares the host Docker daemon, a global # prune would also wipe other homelab services. We never create volumes # here, so only dangling images + build cache are swept. - name: Cleanup if: always() shell: bash run: | docker rmi -f ${{ steps.meta.outputs.sha_tag }} ${{ steps.meta.outputs.branch_tags }} || true docker image prune -f || true docker builder prune -f || true