..

Otomatisasi workflow Flutter dengan CI/CD menggunakan Github Actions πŸš€ (dari Github ke PlayConsole)


Intro

CI/CD digunakan untuk mempermudah developer dalam melakukan proses build, test, dan deploy aplikasi. Dengan CI/CD, developer tidak perlu melakukan build, test, dan deploy secara manual. CI/CD akan melakukan build, test, dan deploy secara otomatis. Dengan CI/CD, developer dapat fokus pada proses development aplikasi, sehingga developer dapat menghemat waktu dan meningkatkan produktivitas.

Dalam guide ini akan dibahas bagaimana cara melakukan CI/CD pada aplikasi Flutter menggunakan Github Actions.

Untuk unit test tidak dibahas ya disini hanya fokus ke build dan deploy saja 🀣

Persiapan

  • Punya akun Github dan mengerti dasar-dasarnya (Push, Pull, Fork, PR, dll)
  • Project Flutter yang sudah jalan di lokal (Aktifkan INTERNET PERMISSION di AndroidManifest.xml)
  • (Opsional) Akun Play Console untuk melakukan deploy secara otomatis ke Play Store

Langkah (Build & Deploy Only)

Buat file workflow

File workflow ini akan berisi konfigurasi untuk melakukan build dan deploy aplikasi Flutter. File workflow ini akan berada di folder .github/workflows dengan nama flutter.yml.

  • Buat file workflow dengan nama flutter.yml di folder .github/workflows ( kalau belum ada folder .github/workflows silahkan buat dulu ) image

  • Isi file workflow dengan konfigurasi berikut

  • Kemudian commit dan push ke Github image

  • Jika sudah cek tab Actions di Github, maka akan muncul workflow yang sudah dibuat tadi, tetapi belum berjalan. image

Menjalankan workflow

untuk menjalankan workflow, kita bisa melakukan push tag ke Github sesuai dengan konfigurasi yang sudah dibuat tadi.

Karena kita sudah membuat konfigurasi untuk melakukan build dan deploy ketika ada tag baru, maka kita bisa melakukan push tag ke Github.

  • Buka terminal, lalu masuk ke folder project Flutter
  • (Opsional) Jika ada file yang berubah lakukan commit terlebih dahulu
  • Jalankan perintah git tag v1.0.0 untuk membuat tag baru dengan nama v1.0.0 lalu tekan enter
  • Jalankan perintah git push origin v1.0.0 untuk push tag ke Github lalu tekan enter image
  • Cek tab Actions di Github, maka workflow akan berjalan image
  • Tunggu sampai workflow selesai berjalan (Kurang lebih 5-7 menit) image
  • Jika sudah selesai, cek tab Releases di Github, maka akan muncul release yang sudah dibuat tadi image

Untuk CI/CD sampai Github saja selesai disini ya πŸŽ‰

Langkah (Build, Deploy, dan Integrasi Play Console) (Opsional)

Jika tidak punya akun Play Console, silahkan buat dulu ya harganya $25

Guide yang ini mungkin lebih advanced dari yang atas jadi bear in mind ya πŸ˜…

Guide ini hanya untuk Windows, untuk MacOS dan Linux silahkan cari sendiri ya tapi harusnya sih mirip mirip. atau kalau mau berkontribusi kalau tau caranya untuk Linux dan MacOS silahkan PR ke repo ini ya

Untuk caranya agak sedikit mirip untuk yang di github tapi ada beberapa hal yang berbeda jika sudah masuk Play Console.

Persiapkan Aplikasi

  • Buka file app/build.gradle pada project Flutter kalian
  • Tambahkan line ini di bagian atasnya android
     def keystoreProperties = new Properties()
     def keystorePropertiesFile = rootProject.file('key.properties')
     if (keystorePropertiesFile.exists()) {
         keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
     }
    
     android {
           ...
     }
    
  • Kemudian temukan block code buildTypes
     buildTypes {
         release {
             // TODO: Add your own signing config for the release build.
             // Signing with the debug keys for now,
             // so `flutter run --release` works.
             signingConfig signingConfigs.debug
         }
     }
    
  • Lalu copas semua dengan code ini
     signingConfigs {
         release {
             keyAlias keystoreProperties['keyAlias']
             keyPassword keystoreProperties['keyPassword']
             storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
             storePassword keystoreProperties['storePassword']
         }
     }
     buildTypes {
         release {
             signingConfig signingConfigs.release
         }
     }
    
  • Nanti hasilnya jadi seperti ini

  • Push repository ke Github

Kode diatas diambil dari flutter.dev

Signin app dan build appbundle

Disini kita akan membuat 2 file yaitu keystore.jks dan key.properties, fungsi keystore untuk menandatangani aplikasi kita, sedangkan key.properties untuk menyimpan informasi dari keystore dan mennyambukan dengan app flutter kita.

Kedua file ini tidak akan di push ke Github, karena juga sudah .gitignore secara default

Membuat keystore.jks

Pada contoh Langkah (Build & Deploy Only) appbundles dan apk tersebut tidak dibekali dengan keystore, nah salah satu persyaratan untuk bisa upload di Play Console adalah appbundle dan apk tersebut harus dibekali dengan keystore. Jadi mari kita buat keystore dulu lalu kita sign appbundle dan apk tersebut.

  • Buka terminal, lalu masuk ke folder project Flutter
  • Jalankan perintah
keytool -genkey -v -keystore D:/furniture.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias upload
  • lalu tekan enter

Keystore furniture.jks bisa diganti dengan nama apapun yang kalian inginkan begitu juga dengan alias upload

Path D:/ berarti kita membuat keystore di root drive D, jika kalian ingin membuatnya di drive atau folder lainnya silahkan ganti sesuai dengan drive kalian

  • Akan muncul beberapa prompt yang gak penting silahkan isi sesuai keinginan kalian, jika ditanya password yang pertama (keystore) catat ya, karena nanti kita akan membutuhkannya
  • Kemudian ketikkan β€˜yes’ di akhir prompt image

    Untuk password keystore saya: 123456 (Minimal 6 karakter)

  • Lalu ditanyakan untuk password keduanya (alias) masukkan password (jangan langsung enter), jangan lupa dicatat juga password yang ini image

Untuk password alias saya: 654321 (Minimal 6 karakter dan harus berbeda dgn password keystore)

  • Kalau sudah berhasil akan seperti ini dan file dapat ditemukan di drive D image image

  • Simpan file keystore tersebut di folder yang aman, karena nanti kita akan membutuhkannya untuk upload ke Play Console dan Integrasi dengan Github Action

Untuk tutorial ini saya simpan di root drive D untuk memudahkan saja

One down one to go. File keystore.jks sudah diamankan sekarang tinggal buat file key.properties

Membuat key.properties

  • Pergi ke root folder aplikasi flutter kalian lalu buka folder android
  • Buat file dengan nama key.properties image

  • Buka file tersebut dengan text editor, lalu isi dengan string ini
    storePassword=123456 
    keyPassword=654321
    keyAlias=upload
    storeFile=D:/furniture.jks
    

storePassword dan keyPassword adalah password yang kalian catat tadi, storePassword adalah password keystore dan keyPassword adalah password alias

keyAlias merupakan alias yang kita set tadi

storeFile adalah path keystore.jks yang kita buat tadi karena tadi saya buat di root drive D maka saya arahkan kesana

image

Sign appbundle

file keystore.jks dan key.properties sudah siap, sekarang kita akan sign appbundle dan apk

Jika semua sudah selesai, kita bisa sign appbundle dan apk kita dengan menjalankan perintah ini

flutter build appbundle

Tunggu beberapa saat, jika sudah selesai maka akan muncul file app-release.aab di folder build/app/outputs/bundle/release

Ini adalah app yang sudah di sign dengan keystore yang kita buat tadi

image

To the PlayConsole, we go !

Pastikan sudah buat akun Play Console dulu ya

Tujuan section ini adalah untuk mendapatkan appid yang akan kita gunakan untuk integrasi dengan Github Action, serta Mensetup keystore yang kita generate tadi dengan PlayConsole.

Disini saya menggunakan mode Internal testing jika ingin menggunakan mode perilisan lainnya silahkan disesuaikan

Flow nya kira kira seperti ini

  • Upload Manual 1x untuk mendapatkan app id
  • Setup keystore yang kita buat tadi agar SHA nya sama ketika di deploy lewat Github Action
  • Setelah itu bisa deploy lewat Github Action sepuasnya

Login ke PlayConsole lalu buat aplikasi baru

  • Isikan nama aplikasi, dll lalu Create
  • Pilih Internal testing pada sidebar Play Console
  • Lalu Create a new release

image

  • Ganti metode app signin menggunakan keystore yang sudah kita buat tadi agar tidak ter generate otomatis oleh Google image

  • Pilih Use a different key image

  • Lalu pilih yang Export and upload from Java keystore image

  • Download PEPK tool nya, lalu letakkan di tempat dimana keystore tadi disimpan image

  • Buka terminal lalu ketikkan perintah ini

$ java -jar pepk.jar --keystore=furniture.jks --alias=upload --output=output.zip --include-cert --encryptionkey=eb10fe8f7c7c9df715022017b00c6471f8ba8170b13049a11e6c09ffe3056a104a3bbe4ac5a955f4ba4fe93fc8cef27558a3eb9d2a529a2092761fb833b656cd48b9de6a

image

keystore dengan value furniture,jks adalah nama key yang kita buat tadi, begitu juga dengan alias yang tadi kita namai upload

  • Pencet enter kemudian akan ditanyai 2 password tadi, masukkan keduanya dengan benar

  • Jika sukses maka akan ada file output.zip image

  • Upload file ini ke dalam kolom upload untuk menset key nya image

  • Maka prompt akan berubah menjadi seperti ini image

  • Langkah terakhir upload aab yang digenerate dengan key ini untuk mendapatkan app id image image image

App ID yang didapat adalah com.nighthawk.heh

Dengan ini sudah siap untuk pindah ke Github Action

Working dengan Github Action

Karena file workflow yang sudah dibuat tadi hanya untuk build dan deploy ke Github, maka kita perlu mengedit file workflow tersebut untuk melakukan integrasi ke Play Console.

Tambahkan 2 line ini / uncomment line ini dari file yang sebelumnya sudah dibuat

- name: Decode android/neumodore_key.jks
  run: echo "$" | base64 --decode > android/app/keystore.jks
- name: Decode android/key.properties
  run: echo "$" | base64 --decode > android/key.properties

Fungsi diatas digunakan untuk mendecode file keystore.jks dan key.properties yang akan kita encode pada section selanjutnya. Nah karena kode keystore.js dan key.properties itu sangat sensitif saya sarankan jangan dimasukkan ke version control (Github) karena bisa diakses oleh siapa saja. Jadi saya encode dulu file tersebut lalu masukkan ke Github Secrets dengan metode file ke base64 (karena github secret hanya menerima text).

Hasil jadinya akan seperti ini (copas aja, sudah self explanatory dan sudah kukasih komen)

Click to expand

Push file workflow yang sudah diubah tadi ke Github

Sshh, its our Secret

Notice pada gist diatas ada value seperti KEYSTORE_JKS_PROD dan KEY_PROPERTIES_PROD, dan GOOGLE_SERVICE_JSONKEY itu adalah nama yang kita buat di Github Secrets. Jadi kita perlu membuat 3 secrets dengan nama tersebut.

Kenapa gak langsung di push saja ke Github ? dont please dont. Karena file keystore.jks, key.properties, dan services.json itu sangat sensitif, jadi jangan sampai ada orang yang bisa mengakses file tersebut. Jadi kita encode dulu file tersebut lalu masukkan ke Github Secrets dengan metode file ke base64 (karena github secret hanya menerima text).

Encode KEYSTORE_JKS_PROD ke base64

  • Buka website https://base64.guru/converter/encode/file
  • Buka file lokasi file keystore.jks (disini saya pakai furniture.jks) yang sudah kita buat tadi
  • Upload file ke dalam kolom upload
  • Lalu klik tombol Encode file to base64 image
  • Copy hasilnya (Letakkan di Notepad atau tempat catatan lain untuk sementara)

Encode KEY_PROPERTIES_PROD ke base64

  • Sebelum di encode buka file key.properties dan ubah value storeFile menjadi keystore.jks. Karena hasil decode nama filenya nanti akan diubah secara otomatis menjadi keystore.jks dan tidak furniture.jks image
  • Buka website https://base64.guru/converter/encode/file
  • Buka file lokasi file key.properties yang sudah kita buat tadi
  • Upload file ke dalam kolom upload
  • Lalu klik tombol Encode file to base64 image
  • Copy hasilnya (Letakkan di Notepad atau tempat catatan lain untuk sementara)

Mendapatkan Google Service Json Key

Bisa dibaca lebih lanjut disini

Masukkan hasil encode ke Github Secrets

  • Buka repository Github yang sudah kita buat tadi
  • Pada bagian Settings > Secrets > Action > New repository secret image
  • Masukkan nama KEYSTORE_JKS_PROD dan paste hasil encode dari file keystore.jks tadi image
  • Masukkan nama KEY_PROPERTIES_PROD dan paste hasil encode dari file key.properties tadi image
  • Masukkan nama GOOGLE_SERVICE_JSONKEY dan paste hasil string json dari file services.json image

Pre-launch check

  • Jangan lupa tambahkan version code +1 (kalau udah ada 1 ya pake 2 dst) di pubspec.yaml
  • Jangan lupa beri permission penuh pada app yang mau di publish lewat Play Console image
  • Ceklis semua permission pada Account Permissions image

Menjalankan Workflow

  • Untuk mentrigger workflow buat tag baru dengan format 1.0.0 (sesuaikan dengan versi app yang mau di publish)
  • Jalankan perintah git tag 1.0.0 untuk membuat tag baru dengan nama 1.0.0 lalu tekan enter
  • Jalankan perintah git push origin 1.0.0 untuk push tag ke Github lalu tekan enter

Finishing

  • Tunggu beberapa saat sampai workflow selesai
  • Jika sukses maka akan ada notice seperti ini pada tab Action image
  • Check juga pada Play Console, apakah sudah ada versi baru yang terpublish

Selamat telah berhasil membuat workflow untuk publish app ke Play Store secara otomatis. Mulai sekarang jika ada perubahan baru di app kita tinggal push tag ke Github dan workflow akan otomatis berjalan untuk publish app ke Play Store. Yay πŸŽ‰πŸŽ‰πŸŽ‰