Membangun Aplikasi Android dan iOS di Pipeline CI

Anda memiliki aplikasi mobile yang berhasil dikompilasi di laptop. Anda push kode ke repositori, pipeline CI dimulai, dan sepuluh menit kemudian gagal dengan error yang belum pernah Anda lihat sebelumnya. Versi SDK berbeda. Sebuah dependensi ter-resolve ke rilis yang sedikit lebih baru. Sertifikat signing hilang. Inilah realitas build mobile di CI: apa yang berjalan secara lokal seringkali rusak di pipeline.

Hal pertama yang harus diperbaiki dalam pipeline CI mobile adalah proses build itu sendiri. Bukan hanya menjalankan kompiler, tetapi menghasilkan artefak yang konsisten, dapat diuji, dan siap didistribusikan. Android dan iOS menangani ini secara berbeda, dan masing-masing memiliki jebakannya sendiri.

Build Android dengan Gradle

Build Android berjalan melalui Gradle, yang membaca konfigurasi dari file build.gradle. Tiga pengaturan SDK yang penting di sini: compileSdk, minSdk, dan targetSdk. Mereka mudah tertukar, tetapi masing-masing memiliki tujuan yang berbeda.

compileSdk mengontrol level API mana yang tersedia selama kompilasi. Jika Anda menyetelnya ke 34, Anda dapat menggunakan API yang diperkenalkan di Android 14. minSdk adalah versi Android terendah yang didukung aplikasi Anda. Jika Anda menyetelnya ke 26, perangkat yang menjalankan Android 8.0 atau lebih lama tidak dapat menginstal aplikasi Anda. targetSdk memberi tahu Android versi mana yang telah Anda uji. Saat Anda menargetkan SDK yang lebih baru, Android mungkin menerapkan perubahan perilaku yang memengaruhi aplikasi Anda.

Pipeline harus menggunakan versi SDK yang sama dengan lingkungan pengembangan lokal Anda. Ketidakcocokan sering menyebabkan error kompilasi yang hanya muncul di CI. Tetapkan versi ini secara eksplisit di file build.gradle Anda dan verifikasi di konfigurasi pipeline.

Dependensi adalah sumber masalah umum lainnya. Gradle menarik library dari Maven Central, Google Maven, atau repositori internal Anda. Tanpa caching, pipeline mengunduh setiap dependensi dari awal pada setiap build. Proyek dengan dua puluh dependensi dapat menghabiskan waktu sepuluh hingga lima belas menit hanya untuk mengunduh. Cache direktori dependensi Gradle di antara build. Sebagian besar platform CI mendukung ini dengan perubahan konfigurasi sederhana, dan ini secara signifikan memotong waktu build.

Output dari build Android adalah APK atau AAB. APK adalah format lama yang dapat Anda instal langsung di perangkat. AAB adalah format yang lebih baru yang Anda unggah ke Google Play, yang kemudian menghasilkan APK yang dioptimalkan untuk setiap konfigurasi perangkat. Gunakan APK untuk pengujian internal dan distribusi manual. Gunakan AAB untuk rilis resmi melalui Play Store. Pipeline Anda harus mendukung keduanya, tetapi pilihannya tergantung pada ke mana artefak akan dikirim.

Berikut adalah contoh minimal job GitHub Actions yang membangun aplikasi Android dan menyimpan APK sebagai artefak:

name: Android Build
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'
      - name: Cache Gradle dependencies
        uses: actions/cache@v4
        with:
          path: ~/.gradle/caches
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
          restore-keys: |
            ${{ runner.os }}-gradle-
      - name: Build release APK
        run: ./gradlew assembleRelease
      - name: Upload APK
        uses: actions/upload-artifact@v4
        with:
          name: app-release
          path: app/build/outputs/apk/release/*.apk

Contoh ini menyiapkan JDK, mengaktifkan caching Gradle, menjalankan build rilis, dan mengunggah APK yang dihasilkan. Sesuaikan versi Java dan path wrapper Gradle dengan proyek Anda.

Build iOS dengan Xcode

Build iOS menggunakan Xcode dan sistem build-nya. Pipeline menjalankan xcodebuild dengan parameter yang menentukan skema, konfigurasi (Debug atau Release), dan tujuan (simulator atau perangkat fisik). File proyeknya adalah .xcodeproj atau .xcworkspace. Jika proyek Anda menggunakan CocoaPods, Anda memerlukan file workspace.

Manajemen dependensi adalah tempat build iOS sering gagal. Banyak proyek iOS menggunakan CocoaPods, Swift Package Manager, atau Carthage. Pipeline harus menjalankan pod install atau swift package resolve sebelum membangun. Jika versi yang di-resolve di CI berbeda dari yang digunakan tim Anda secara lokal, Anda akan mendapatkan error yang sulit di-debug. Kunci versi dependensi Anda. CocoaPods menghasilkan file Podfile.lock. Commit file tersebut ke repositori dan pastikan pipeline menggunakannya.

Output dari build iOS adalah file IPA. Tidak seperti APK, IPA adalah bundel yang berisi aplikasi yang sudah ditandatangani. Pipeline biasanya menghasilkan dua varian: IPA pengembangan untuk pengujian internal dengan sertifikat pengembangan, dan IPA distribusi untuk App Store. Keduanya memerlukan signing yang tepat, yang akan kita bahas secara terpisah.

Menyimpan Artefak Build

Baik build Android maupun iOS menghasilkan artefak yang perlu disimpan. Pendekatan paling sederhana adalah menggunakan penyimpanan artefak bawaan platform CI Anda. Untuk tim yang lebih besar atau alur kerja yang lebih kompleks, unggah artefak ke lokasi bersama seperti S3 atau Google Cloud Storage.

Diagram berikut menunjukkan bagaimana pipeline build Android dan iOS berjalan secara paralel dan bertemu di penyimpanan artefak.

flowchart TD A[Checkout Kode] --> B[Android: Gradle Build] A --> C[iOS: Xcode Build] B --> D[APK / AAB] C --> E[IPA] D --> F[Penyimpanan Artefak] E --> F F --> G[Versi & Nomor Build]

Setiap artefak membutuhkan pengidentifikasi yang jelas. Sertakan nomor versi dan nomor build dalam nama file atau metadata. Anda harus dapat melacak artefak apa pun kembali ke commit tepat yang menghasilkannya. Tanpa ini, debugging masalah produksi menjadi tebak-tebakan.

Daftar Periksa Praktis

Sebelum Anda menyatakan pipeline build mobile Anda siap, jalankan daftar periksa singkat ini:

  • Versi SDK di build.gradle cocok antara lingkungan lokal dan CI
  • Caching dependensi Gradle diaktifkan
  • Podfile.lock atau yang setara di-commit dan digunakan di CI
  • Skema dan konfigurasi Xcode ditetapkan secara eksplisit di pipeline
  • Nama file artefak menyertakan versi dan nomor build
  • Artefak build disimpan dan dapat diakses setelah pipeline selesai

Kesimpulan

Pipeline build mobile bukan hanya tentang menjalankan kompiler. Ini tentang mereproduksi lingkungan, dependensi, dan konfigurasi yang sama setiap saat. Ketika build lokal Anda berfungsi tetapi pipeline gagal, masalahnya hampir selalu terletak pada perbedaan di salah satu dari tiga hal ini. Kunci semuanya, lakukan caching secara agresif, dan beri nama artefak Anda dengan jelas. Sisa pipeline bergantung pada langkah pertama yang benar ini.