🎬 Manim Android APK Build (Production) #13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: 🎬 Manim Android APK Build (Production) | |
| on: | |
| push: | |
| branches: [ "main", "develop" ] | |
| paths: | |
| - 'main.py' | |
| - 'buildozer.spec' | |
| - '.github/workflows/manim-android-production.yml' | |
| - 'src/**' | |
| pull_request: | |
| branches: [ "main" ] | |
| workflow_dispatch: | |
| inputs: | |
| build_type: | |
| description: 'Build type (debug/release)' | |
| required: true | |
| default: 'debug' | |
| type: choice | |
| options: | |
| - debug | |
| - release | |
| concurrency: | |
| group: build-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| validate: | |
| name: 📋 Validate Configuration | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Check Required Files | |
| run: | | |
| [ -f "buildozer.spec" ] || (echo "❌ buildozer.spec missing!" && exit 1) | |
| [ -f "main.py" ] || (echo "❌ main.py missing!" && exit 1) | |
| echo "✅ Required files present" | |
| - name: Validate buildozer.spec | |
| run: | | |
| grep -q "^\[app\]" buildozer.spec || (echo "❌ Missing [app] section" && exit 1) | |
| grep -q "^title" buildozer.spec || (echo "❌ Missing title" && exit 1) | |
| grep -q "^package.name" buildozer.spec || (echo "❌ Missing package.name" && exit 1) | |
| grep -q "^package.domain" buildozer.spec || (echo "❌ Missing package.domain" && exit 1) | |
| echo "✅ buildozer.spec valid" | |
| - name: Check Python Syntax | |
| run: python3 -m py_compile main.py | |
| build: | |
| name: 🏗️ Build APK | |
| runs-on: ubuntu-latest | |
| needs: validate | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Free Disk Space | |
| uses: jlumbroso/free-disk-space@main | |
| with: | |
| tool-cache: false | |
| android: false | |
| dotnet: true | |
| haskell: true | |
| large-packages: true | |
| swap-storage: true | |
| - name: Set up Java 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '17' | |
| distribution: 'temurin' | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.11' | |
| - uses: actions/cache@v3 | |
| with: | |
| path: | | |
| ~/.cache/pip | |
| ~/.local/lib/python3.11/site-packages | |
| key: manim-pip-${{ hashFiles('**/requirements.txt') }}-py3.11 | |
| restore-keys: manim-pip-py3.11 | |
| - uses: actions/cache@v3 | |
| with: | |
| path: | | |
| ~/.buildozer | |
| ~/.local/share/python-for-android | |
| key: buildozer-${{ hashFiles('buildozer.spec') }} | |
| restore-keys: buildozer-cache | |
| - uses: actions/cache@v3 | |
| with: | |
| path: | | |
| ~/Android/sdk | |
| ~/.android | |
| key: android-sdk-${{ runner.os }}-${{ hashFiles('buildozer.spec') }} | |
| restore-keys: android-sdk-cache | |
| - name: Install Python & Build Dependencies | |
| run: | | |
| python -m pip install --upgrade pip setuptools wheel | |
| pip install Cython==0.29.33 setuptools-scm buildozer python-for-android | |
| pip install numpy scipy matplotlib pillow sympy pydub requests watchdog opencv-python scikit-image imageio imageio-ffmpeg | |
| - name: Install System Dependencies | |
| run: | | |
| sudo apt-get update -qq | |
| sudo apt-get install -y build-essential git curl wget pkg-config autoconf automake libtool m4 gettext cmake ninja-build | |
| sudo apt-get install -y libcairo2-dev libpango1.0-dev libfreetype6-dev fonts-liberation fonts-dejavu-core libharfbuzz-dev libfribidi-dev | |
| sudo apt-get install -y libpng-dev zlib1g-dev libjpeg-dev | |
| sudo apt-get install -y ffmpeg libavformat-dev libavcodec-dev libavdevice-dev libswscale-dev libswresample-dev libavutil-dev libavfilter-dev | |
| sudo apt-get install -y libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev | |
| sudo apt-get install -y libglib2.0-dev gobject-introspection libgirepository1.0-dev | |
| sudo apt-get install -y libxml2-dev libxslt1-dev | |
| sudo apt-get install -y libssl-dev libffi-dev libbz2-dev xz-utils unzip | |
| sudo apt-get install -y texlive texlive-latex-base texlive-latex-extra texlive-fonts-extra texlive-fonts-recommended texlive-science texlive-latex-recommended cm-super dvipng dvisvgm | |
| - name: Set up Android SDK/NDK | |
| uses: android-actions/setup-android@v3 | |
| with: | |
| packages: > | |
| platforms;android-31 | |
| ndk;25.2.9519653 | |
| cmake;3.22.1 | |
| build-tools;34.0.0 | |
| - name: Verify Dependencies | |
| run: | | |
| pkg-config --modversion cairo | |
| pkg-config --modversion pango | |
| pkg-config --modversion freetype2 | |
| pkg-config --modversion harfbuzz | |
| latex --version | |
| ffmpeg -version | |
| python -c "import numpy; import PIL; import scipy" | |
| - name: Configure Build | |
| run: | | |
| echo "=== buildozer.spec ===" | |
| cat buildozer.spec | |
| echo "=== main.py (first 50 lines) ===" | |
| head -50 main.py | |
| - name: Build APK (Debug/Release) | |
| run: | | |
| export BUILDOZER_LOG_LEVEL=2 | |
| yes | buildozer android ${{ github.event.inputs.build_type }} 2>&1 | tee buildozer-build.log | |
| timeout-minutes: 120 | |
| continue-on-error: true | |
| - name: Verify APK Output | |
| if: always() | |
| run: | | |
| APK_COUNT=$(find . -name "*.apk" 2>/dev/null | wc -l) | |
| echo "APK files found: $APK_COUNT" | |
| [ $APK_COUNT -gt 0 ] && find . -name "*.apk" -exec ls -lh {} \; | |
| - name: Upload Artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: manim-android-apk | |
| path: bin/ | |
| retention-days: 30 | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: buildozer-logs | |
| path: buildozer-build.log | |
| retention-days: 30 | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: buildozer-work-dir | |
| path: .buildozer/ | |
| retention-days: 7 | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: build-config | |
| path: buildozer.spec | |
| retention-days: 30 | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: app-source | |
| path: main.py | |
| retention-days: 30 | |
| - name: Build Summary | |
| run: | | |
| shopt -s nullglob | |
| APK_FILES=(bin/*.apk) | |
| if [ ${#APK_FILES[@]} -gt 0 ]; then | |
| echo "✅ Build completed" | |
| ls -lh "${APK_FILES[@]}" | |
| else | |
| echo "⚠️ Build failed" | |
| fi | |
| release: | |
| name: 📤 Release & Upload Artifacts | |
| runs-on: ubuntu-latest | |
| needs: build | |
| if: always() | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: manim-android-apk | |
| path: artifacts/apk/ | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: buildozer-logs | |
| path: artifacts/logs/ | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: build-config | |
| path: artifacts/config/ | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: app-source | |
| path: artifacts/source/ | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: buildozer-work-dir | |
| path: artifacts/buildozer/ | |
| - name: Create Release Package | |
| run: | | |
| mkdir -p release-files | |
| cp -r artifacts/* release-files/ 2>/dev/null | |
| cat > release-files/MANIFEST.txt << 'EOF' | |
| 🎬 Manim Android Build Release | |
| =============================== | |
| Contents: | |
| - apk/ : APK files | |
| - logs/ : Buildozer build logs | |
| - config/ : buildozer.spec | |
| - source/ : main.py | |
| - buildozer/: Full buildozer work dir | |
| Instructions: | |
| 1. Extract | |
| 2. adb install -r apk/*.apk | |
| 3. Check logs/ if APK missing | |
| 4. Review buildozer/ for details | |
| EOF | |
| ls -lah release-files/ | |
| - name: Release to GitHub | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| files: | | |
| release-files/apk/*.apk | |
| release-files/logs/* | |
| release-files/config/* | |
| release-files/source/* | |
| release-files/MANIFEST.txt | |
| draft: false | |
| prerelease: false | |
| fail_on_unmatched_files: false | |
| tag_name: build-${{ github.run_number }}-${{ github.run_id }} | |
| name: "Manim Android Build #${{ github.run_number }}" | |
| body: | | |
| 🎬 **Manim Android APK Build Release** | |
| - Run: #${{ github.run_number }} | |
| - Commit: ${{ github.sha }} | |
| - Branch: ${{ github.ref }} | |
| - Date: ${{ github.event.head_commit.timestamp }} | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |