Belajar Hermes JS Engine - Build Systems, CI & Release
Episode 19 of 23

Belajar Hermes JS Engine - Build Systems, CI & Release

Episode ini menyusun pipeline CI untuk Hermes builds: mendefinisikan job yang memproduksi bytecode secara deterministik, menangkap dan memvalidasi bytecode serta source maps, lalu menegakkan deployment checks untuk release Android dan iOS.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Pendahuluan

Episode 18 menutup dengan crash reporting dan native stack traces — bagaimana menyimbolkan laporan crash menjadi informasi yang bisa ditindaklanjuti. Sekarang kita masuk Fase 6 dan mulai menutup lubang terakhir sebelum production: kepercayaan terhadap build. Kalau setiap developer membangun dengan cara berbeda, yang sampai ke pengguna bukanlah artefak yang kalian validasi.

Roadmap episode 19: pipeline CI untuk Hermes builds, menangkap artefak yang konsisten, validasi bytecode dan source maps, lalu deployment checks untuk release Android dan iOS.

Mendefinisikan Pipeline CI untuk Hermes Builds

Pipeline CI untuk aplikasi Hermes harus menghasilkan artefak yang sama seperti build lokal yang tervalidasi. Setiap push ke cabang main (atau PR) seharusnya memicu job yang: checkout source, pasang dependencies, kompilasi bytecode Hermes, lalu membangun release. Contoh pipeline GitHub Actions:

Pipeline CI untuk Hermes builds
name: hermes-release
on:
  pull_request:
    branches: [main]
  push:
    branches: [main]
 
jobs:
  build-android:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - name: Install dependencies
        run: bun install --frozen-lockfile
      - name: Generate bytecode Hermes
        run: |
          npx react-native bundle --platform android --dev false \
            --entry-file index.js --bundle-output index.android.bundle
          hermesc -O -emit-binary -out index.android.hbc index.android.bundle
      - name: Build release APK
        working-directory: android
        run: ./gradlew assembleRelease
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: android-release
          path: android/app/build/outputs/apk/release/

Info

CI membutuhkan environment yang deterministik. Gunakan runner yang terpisah antara Android (Ubuntu) dan iOS (macOS), dan pastikan versi JDK, Node, serta Hermes dikunci — jangan pernah membiarkan CI mengambil "versi terbaru" secara liar.

Pipeline di atas memproduksi bytecode secara eksplisit dengan hermesc. Di React Native modern, gradle melakukan langkah ini otomatis saat assembleRelease; memproduksinya eksplisit di CI memberi kalian kontrol dan artefak yang bisa divalidasi lebih dulu sebelum masuk ke dalam APK.

Menangkap Artefak Build yang Konsisten

Validasi tidak ada gunanya kalau artefak hilang. Untuk build Hermes, minimal simpan empat artefak yang diindeks oleh versi:

  • Bytecode .hbc (atau .bundle hasil Hermes).
  • Source map .hbc.map untuk deobfuscation stack trace.
  • Simbol native (library .so di Android atau dSYM di iOS).
  • Manifes dengan checksum SHA-256 untuk setiap artefak.

Konsistensi dimulai dari flag kompiler yang sama untuk semua developer dan CI. Kunci flag di gradle supaya tidak bisa diganti diam-diam:

Kunci flag Hermes di build.gradle
react {
  hermesFlags = ["-O", "-output-source-map"]
}

Dengan -output-source-map, gradle menghasilkan file .hbc.map berpasangan dengan bytecode. Arsipkan keduanya dengan nama yang memuat versi rilis, misalnya app-1.4.0.hbc dan app-1.4.0.hbc.map — karena stack trace produksi tanpa source map yang cocok hanya akan menjadi teka-teki.

Validasi Release Build, Bytecode, dan Source Maps

CI harus gagal jika bytecode aneh. hbcdump bisa memeriksa isi file .hbc — jumlah function, versi bytecode, hingga disassembly jika perlu:

Validasi bytecode dan source map
hbcdump -function-sources index.android.hbc
shasum -a 256 index.android.hbc index.android.hbc.map
node scripts/verify-sourcemap.mjs index.android.hbc.map

Langkah wajib lainnya: verifikasi source map. Ambil beberapa alamat dari stack trace contoh, petakan lewat tool symbolication, dan pastikan hasilnya mengarah ke baris file sumber yang benar. Source map yang "tidak nyambung" akan membuat error produksi tidak bisa dilacak. Untuk menjalankan pemeriksaan ini otomatis, tambahkan step node scripts/verify-sourcemap.mjs ke pipeline sebagai gerbang sebelum upload artefak.

Warning

Bytecode Hermes terkunci ke versi engine. Jika versi Hermes di gradle berbeda dari versi hermesc yang dipakai membuat .hbc di CI, hasilnya bisa menjadi bytecode yang tidak bisa dieksekusi atau error misterius di runtime. Selalu pakai versi yang sama di semua langkah.

Deployment Checks untuk Android Release

Sebelum APK dirilis, jalankan verifikasi otomatis:

Deployment checks Android
cd android && ./gradlew assembleRelease
apksigner verify --print-certs app/build/outputs/apk/release/app-release.apk
unzip -p app/build/outputs/apk/release/app-release.apk \
  assets/index.android.bundle | head -c 4 | xxd

Tiga hal yang dicek: build sukses, APK ditandatangani dengan sertifikat yang benar, dan aset bundle dimulai dengan magic bytes bytecode Hermes (bukan JavaScript polos). Magic bytes yang tampil sebagai opcode Hermes memastikan runtime Hermes yang akan mengeksekusi, bukan JavaScript interpreter yang lambat. Verifikasi ini juga melindungi kalian dari build yang tanpa sengaja mematikan Hermes.

Deployment Checks untuk iOS Release

Di macOS, gunakan xcodebuild untuk archive dan verifikasi tanda tangan serta konten:

Deployment checks iOS
xcodebuild archive -workspace App.xcworkspace -scheme App -configuration Release
codesign --verify --deep --strict build/Release-iphoneos/App.app
file build/Release-iphoneos/App.app/main.jsbundle

file pada main.jsbundle di iOS juga harus melaporkan bytecode Hermes. Jika laporan menunjukkan teks (alias JavaScript polos), berarti kompilasi Hermes tidak berjalan dan performa startup kalian akan mengecewakan di production.

Penutup

Build yang bisa direproduksi adalah fondasi dari semua diskusi observability dan release automation di dua episode terakhir nanti. CI bukan tempat untuk "menemukan" masalah — itu harus menjadi gerbang yang menolak artefak yang tidak sesuai standar sebelum mencapai pengguna.

Inti yang harus dibawa pulang:

  • CI harus memproduksi bytecode secara eksplisit dan deterministik dengan flag Hermes yang sama di semua environment.
  • Simpan bytecode, source map, simbol native, dan checksum per versi rilis.
  • Validasi bytecode dengan hbcdump dan verifikasi source map dengan symbolication contoh.
  • Pastikan APK dan IPA benar-benar memuat bytecode Hermes, bukan JavaScript polos.
  • Verifikasi penandatanganan aplikasi (apksigner dan codesign) sebelum upload ke toko.

Di episode 20, kita lanjut ke Observability & Performance Monitoring: memantau metrik runtime startup, memori, dan eksekusi JavaScript, lalu menetapkan performance budgets yang bisa ditegakkan. Sampai jumpa!

Belajar Hermes JS Engine - Build Systems, CI & Release | Belajar Hermes JS Engine