name: DroidMind CI/CD π
on:
push:
branches: [main]
tags:
- "v*"
pull_request:
branches: [main]
workflow_dispatch:
jobs:
build-and-test: # ποΈ Build, Lint & Test π§ͺ
name: ποΈ Build, Lint & Test π§ͺ
runs-on: ubuntu-latest
steps:
- name: π°οΈ Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Needed for `softprops/action-gh-release` to generate release notes
- name: π Set up Python Environment
uses: actions/setup-python@v5
with:
python-version: "3.13"
cache-dependency-path: "pyproject.toml"
- name: β‘ Install uv Build System
uses: astral-sh/setup-uv@v6
- name: π¦ Install Project Dependencies
run: uv sync --all-groups
- name: π
Run DroidMind Lint Script
run: uv run python scripts/lint.py
- name: π§ͺ Execute Pytest Suite
run: uv run pytest
- name: π Upload Test Results Artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-${{ github.sha }}
path: test-results/ # Adjust if your pytest output path is different
- name: π§ Set up QEMU (for multi-platform builds)
uses: docker/setup-qemu-action@v3
- name: π οΈ Set up Docker Buildx Engine
uses: docker/setup-buildx-action@v3
- name: π³ Build Docker Image (no push)
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
push: false
tags: droidmind:latest,droidmind:${{ github.sha }}
build-docs: # π Build Documentation Site π
name: π Build Documentation Site π
needs: [build-and-test]
runs-on: ubuntu-latest
steps:
- name: π°οΈ Checkout Repository
uses: actions/checkout@v4
- name: π Set up Python Environment
uses: actions/setup-python@v5
with:
python-version: "3.13"
cache-dependency-path: "pyproject.toml"
- name: β‘ Install uv Build System
uses: astral-sh/setup-uv@v6
- name: π Install Documentation Dependencies
run: uv sync --all-groups
- name: ποΈ Build MkDocs Site
run: uv run mkdocs build --config-file mkdocs.yml
- name: π€ Upload Documentation Artifact
uses: actions/upload-artifact@v4
with:
name: site-${{ github.sha }}
path: site
deploy-docs: # π Deploy Documentation to GitHub Pages π
name: π Deploy Documentation to GitHub Pages π
needs: [build-docs]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
permissions:
contents: write
steps:
- name: π°οΈ Checkout Repository
uses: actions/checkout@v4
- name: π₯ Download Built Documentation Artifact
uses: actions/download-artifact@v4
with:
name: site-${{ github.sha }}
path: site
- name: π Publish to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./site
create-release: # π Create GitHub Release β¨
name: π Create GitHub Release β¨
needs: [build-and-test, deploy-docs]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
permissions:
contents: write
steps:
- name: π°οΈ Checkout Repository (full history)
uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for release notes generation
- name: π·οΈ Generate GitHub Release Notes
uses: softprops/action-gh-release@v2
with:
name: Release ${{ github.ref_name }}
generate_release_notes: true
# files: | # Optional: attach files like .whl or .tar.gz to the release
# dist/*.whl
# dist/*.tar.gz
publish-pypi: # π Publish Python Package to PyPI π¦
name: π Publish Python Package to PyPI π¦
needs: create-release
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
permissions:
id-token: write # For trusted PyPI publishing
steps:
- name: π°οΈ Checkout Repository
uses: actions/checkout@v4
- name: π Set up Python Environment
uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: β‘ Install uv Build System
uses: astral-sh/setup-uv@v6
- name: π οΈ Build Python Package
run: |
uv pip install --system build
python -m build
- name: π Publish to PyPI via Trusted Publisher
uses: pypa/gh-action-pypi-publish@release/v1
publish-docker: # π³ Publish Docker Image to Registries π’
name: π³ Publish Docker Image to Registries π’
needs: create-release
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
permissions:
contents: read
packages: write
id-token: write # If using OIDC for Docker Hub
steps:
- name: π°οΈ Checkout Repository
uses: actions/checkout@v4
- name: π Extract Version from Git Tag
id: get_version
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: π§ Set up QEMU (for multi-platform builds)
uses: docker/setup-qemu-action@v3
- name: π οΈ Set up Docker Buildx Engine
uses: docker/setup-buildx-action@v3
- name: π Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: π Login to GitHub Container Registry (GHCR)
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: π Build & Push Docker Images to Registries
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
push: true
platforms: linux/amd64,linux/arm64
tags: |
hyperb1iss/droidmind:latest
hyperb1iss/droidmind:${{ steps.get_version.outputs.VERSION }}
ghcr.io/${{ github.repository }}:latest
ghcr.io/${{ github.repository }}:${{ steps.get_version.outputs.VERSION }}
labels: |
org.opencontainers.image.title=DroidMind
org.opencontainers.image.description=Control Android devices with AI through the Model Context Protocol
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.version=${{ steps.get_version.outputs.VERSION }}
org.opencontainers.image.created=${{ github.event.repository.updated_at }}
org.opencontainers.image.revision=${{ github.sha }}