gpui-mobile 0.1.0

Mobile platform support for GPUI — iOS (Metal/Blade) and Android (wgpu/Vulkan)
Documentation
name: CI — Build & Test

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  # ─────────────────────────────────────────────────────────────────────────────
  # Host check + unit tests (macOS — needed for iOS SDK headers)
  # ─────────────────────────────────────────────────────────────────────────────
  host:
    name: Host Check & Tests
    runs-on: macos-14 # Apple Silicon runner — has Xcode + iOS SDKs
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy, rustfmt

      - name: Cache Cargo registry + git deps
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: host-cargo-${{ hashFiles('Cargo.lock', 'Cargo.toml') }}
          restore-keys: host-cargo-

      - name: cargo check (host)
        run: cargo check --all-targets

      - name: cargo test (unit tests)
        run: cargo test --lib

      - name: cargo fmt --check
        run: cargo fmt --all -- --check

      - name: cargo clippy
        run: cargo clippy --all-targets -- -D warnings || true
        # clippy warnings are informational for now; don't fail the build

  # ─────────────────────────────────────────────────────────────────────────────
  # iOS cross-compilation
  # ─────────────────────────────────────────────────────────────────────────────
  ios:
    name: iOS Build (${{ matrix.target }})
    runs-on: macos-14
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: aarch64-apple-ios
            label: device
          - target: aarch64-apple-ios-sim
            label: simulator
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust toolchain + iOS target
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}

      - name: Cache Cargo registry + git deps
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ios-${{ matrix.target }}-cargo-${{ hashFiles('Cargo.lock', 'Cargo.toml') }}
          restore-keys: ios-${{ matrix.target }}-cargo-

      - name: cargo check — gpui-mobile (${{ matrix.label }})
        run: cargo check --target ${{ matrix.target }}

      - name: cargo check — example app (${{ matrix.label }})
        working-directory: examples
        run: cargo check --target ${{ matrix.target }} --features "ios,font-kit"

  # ─────────────────────────────────────────────────────────────────────────────
  # Android cross-compilation
  # ─────────────────────────────────────────────────────────────────────────────
  android:
    name: Android Build (aarch64)
    runs-on: ubuntu-latest
    env:
      ANDROID_NDK_VERSION: "27.0.12077973"
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust toolchain + Android target
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: aarch64-linux-android

      - name: Set up Android SDK + NDK
        uses: android-actions/setup-android@v3
        with:
          accept-android-sdk-licenses: true

      - name: Install NDK
        run: |
          sdkmanager --install "ndk;${{ env.ANDROID_NDK_VERSION }}"
          echo "ANDROID_NDK_HOME=$ANDROID_HOME/ndk/${{ env.ANDROID_NDK_VERSION }}" >> "$GITHUB_ENV"

      - name: Add NDK toolchain to PATH
        run: |
          TOOLCHAIN_DIR="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin"
          echo "$TOOLCHAIN_DIR" >> "$GITHUB_PATH"
          # Verify the linker / compiler is available
          ls "$TOOLCHAIN_DIR"/aarch64-linux-android*-clang || true

      - name: Configure Cargo for Android cross-compilation
        run: |
          mkdir -p .cargo
          cat >> .cargo/config.toml <<'EOF'
          [target.aarch64-linux-android]
          linker = "aarch64-linux-android35-clang"
          EOF
          cat .cargo/config.toml

      - name: Cache Cargo registry + git deps
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: android-cargo-${{ hashFiles('Cargo.lock', 'Cargo.toml') }}
          restore-keys: android-cargo-

      - name: cargo check — gpui-mobile (Android aarch64)
        run: cargo check --target aarch64-linux-android

      - name: cargo check — example app (Android aarch64)
        working-directory: examples
        run: cargo check --target aarch64-linux-android

  # ─────────────────────────────────────────────────────────────────────────────
  # Android APK build (Gradle)
  # ─────────────────────────────────────────────────────────────────────────────
  android-apk:
    name: Android APK (Gradle)
    runs-on: ubuntu-latest
    needs: android
    env:
      ANDROID_NDK_VERSION: "27.0.12077973"
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust toolchain + Android target
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: aarch64-linux-android

      - name: Install cargo-ndk
        run: cargo install cargo-ndk

      - name: Set up Android SDK + NDK
        uses: android-actions/setup-android@v3
        with:
          accept-android-sdk-licenses: true

      - name: Install NDK
        run: |
          sdkmanager --install "ndk;${{ env.ANDROID_NDK_VERSION }}"
          echo "ANDROID_NDK_HOME=$ANDROID_HOME/ndk/${{ env.ANDROID_NDK_VERSION }}" >> "$GITHUB_ENV"

      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: 17

      - name: Cache Cargo registry + git deps
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            examples/target
          key: android-apk-cargo-${{ hashFiles('examples/Cargo.lock', 'examples/Cargo.toml') }}
          restore-keys: android-apk-cargo-

      - name: Build Rust shared library via cargo-ndk
        working-directory: examples
        run: |
          cargo ndk \
            -t arm64-v8a \
            -o android/gradle/app/src/main/jniLibs \
            build

      - name: Assemble debug APK
        working-directory: examples/android/gradle
        run: ./gradlew assembleDebug

      - name: Upload APK artifact
        uses: actions/upload-artifact@v4
        with:
          name: gpui-example-debug.apk
          path: examples/android/gradle/app/build/outputs/apk/debug/app-debug.apk
          retention-days: 7