Skip to content

Environment dan deploy

Bagaimana perubahan yang sudah di-merge berjalan dari GitHub ke situs QA lalu ke server produksi klien. Mekanismenya sama untuk setiap instance klien; langkah terakhirnya berbeda per klien.

Cara halaman ini diverifikasi

Dibaca dari folder deploy master dan lima fork klien pada 2026-09-05 dan 2026-09-06, dari README consumer di twin terenkripsi, dan dari skrip rilis di Rumah box.

Tiga box

Binari menjalankan tiga mesin dengan runner GitHub Actions self-hosted. Setiap deploy adalah job workflow di salah satunya; menit milik GitHub tidak pernah dipakai.

BoxDi manaLabel runnerYang dilakukan
Rumah boxRumah, IP publikrumahproducer untuk setiap instance klien; consumer dan situs QA untuk Jadestone, JOTRE dan Timas; QA master di MySQL dan PostgreSQL; checkout QA KTP
Lab boxLAN kantorlabconsumer dan situs QA untuk Medco (SQL Server-nya hanya bisa dijangkau dari LAN); QA master di SQL Server
Windows Server boxLAN kantor, Windows Server 2022, IISwinserver2022consumer dan situs QA untuk Tomori

Database QA untuk situs di Rumah box berjalan di box itu sendiri; dua database QA Medco berjalan di host database dev bersama. Lihat masing-masing halaman instance.

Producer dan consumer

Klien dikirimi dua repository: yang plain tempat developer bekerja, dan twin terenkripsi yang menyimpan build ionCube. Tidak ada yang menyajikan repository plain di situs klien.

push ke development / main
   → workflow di Rumah box menjalankan deploy/dev.sh atau deploy/prod.sh   (PRODUCER)
   → lib/sync.sh menyalin perubahan yang dilacak git plain → terenkripsi
   → push terenkripsi ke GitHub dan ke GitLab INARTS
   → workflow milik repo terenkripsi terpicu                                (CONSUMER)
   → consumer menarik checkout yang di-serve dan menjalankan phinx migrate

Producer tidak pernah menyentuh web root; ia bekerja di workspace deployer tetap ~/deployer/<env>/<repo>{,-encrypted} di Rumah box. Push ke repo terenkripsi dibuat dengan kunci SSH runner, bukan GITHUB_TOKEN, karena push dengan token tidak akan memicu workflow consumer. Tidak ada loop: consumer tidak pernah push balik.

lib/sync.sh punya dua daftar:

  • SYNC_PROTECT: file yang versinya dipertahankan repo terenkripsi. main.php di mana-mana (itu file ter-encode), plus setting.php di Medco. Kalau source mengubah file yang dilindungi, sinkronisasi meng-commit selebihnya, menulis .sync-blocked dan berhenti sebelum push, supaya orang meng-encode ulang manual.
  • SYNC_IGNORE: deploy/ dan .github/. Setiap repository menyimpan alat deploy-nya sendiri, dan tidak ada yang sampai ke klien. Push yang hanya mengubah path yang diabaikan memperbarui repository plain tetapi tidak membuat commit terenkripsi.

Sinkronisasi juga menolak diff terbalik atau bercabang, dan workflow memakai grup konkurensi plus flock supaya dua deploy dari satu branch tidak pernah tumpang tindih.

Per branch, per instance

Instancedevelopmentstagingmain
Jadestoneconsumer di Rumah box menarik ~/www/inact-jadestone-encrypted dan migratepush staging ke INARTS, lalu ssh ke jadestone.inactsoft.com dan tarik repository plain plus migratemain terenkripsi di-push ke GitHub dan INARTS; tanpa consumer, klien menarik dari INARTS
Medcoproducer di Rumah box, consumer di Lab box menarik dua served root dan migrate masing-masingtidak adamain terenkripsi di-push; tanpa consumer; zip rilis dipasang manual di server tanpa internet
JOTREconsumer di Rumah boxtidak ada, meski branch-nya adamain terenkripsi di-push; tanpa consumer; Eris menarik ke mesin klien lewat VPN
Timasconsumer di Rumah boxtidak ada branchpush ke GitHub memicu deploy/prod.sh di twin terenkripsi, yang ssh ke edms.timas.com, menarik dari INARTS dan migrate
Tomoriproducer di Rumah box, consumer di Windows Server box menarik situs IIS dan migratetidak ada branchmain terenkripsi di-push; zip rilis yang dibuat dari tag dipasang manual
Masterhanya main: deploy/rumah.sh menarik dan migrate checkout QA MySQL dan PostgreSQL, deploy/lab.sh yang SQL Server, dan keduanya me-mirror main ke INARTS

Setup master adalah fan-out QA saja: satu branch, tanpa twin terenkripsi, tanpa sinkronisasi. deploy/README.md-nya memperingatkan dengan huruf kapital bahwa fork klien baru harus mengganti seluruh folder deploy/ dan workflow-nya dengan pola producer/consumer yang disalin dari instance yang sudah dimigrasi.

Apa itu situs QA

SitusBox
inact-mysql.bdt.dev, inact-psql.bdt.devRumah box
inact-sqlsrv.bdt.devLab box
inact-jadestone-encrypted.bdt.dev, inact-jotre-encrypted.bdt.dev, inact-timas-encrypted.bdt.devRumah box
inact-medco-v3-encrypted.bdt.dev, inact-medco-v3-encrypted-testable.bdt.devLab box
inact-tomori-encrypted.bdt.devWindows Server box
inact-ktp.bdt.devRumah box, diperbarui manual

Aturannya: instance yang dikirim terenkripsi mendapat -encrypted di hostname QA-nya. Di sinilah juga build ter-encode diuji, karena file ter-encode tidak bisa jalan di Mac Apple silicon.

Migrasi

  • Dev dan staging migrate sendiri. Setiap consumer menjalankan phinx migrate setelah pull. Migrasi yang di-merge ke development sampai ke database dev bersama dengan sendirinya. Jangan pernah cantumkan "jalankan migrasi di dev" sebagai tugas terbuka.
  • Produksi manual kecuali Timas. Consumer prod Timas migrate. Jadestone dan JOTRE ditarik manual dan di-migrate manual. Medco dan Tomori menerima file migrasi di dalam zip rilis dan menjalankan phinx di lokasi: Tomori dengan C:\php\php.exe .\vendor\bin\phinx migrate di bawah IIS, menurut catatan tim.
  • Eksekusi lokal hanya menyentuh snapshot-mu. Itu bukan bukti dev bersama sudah di-migrate; deployer sudah menanganinya.

TODO: catatan tim menyebut run_sql.php untuk menjalankan SQL di server produksi yang tidak punya klien SQL. Ia tidak ada di repository mana pun yang dibaca pada 2026-09-06; di mana letaknya dan kapan dipakai perlu satu baris di sini.

Memotong rilis produksi

Untuk klien yang dikirimi zip (Medco, Tomori) rilis dipotong di Rumah box dengan ~/apps/deployer/lib/inact-release.sh <repo-terenkripsi> <slug>:

  1. Ia memberi tag pada branch rilis repository terenkripsi (main secara default). Ia tidak memajukan branch; producer sudah melakukannya dari main plain, jadi model branch tetap satu-satunya gerbang untuk apa yang mencapai produksi.
  2. Ia mengemas diff terhadap tag sebelumnya sebagai releases/updates-<slug>-<TAG>.zip, plus <TAG>-DELETED.txt yang mencantumkan path yang dihapus.
  3. Opsi: --dry-run, --no-push, --prev <tag>, --branch <name>.

Zip itu lalu dibawa ke lokasi klien dan dipasang manual, termasuk migrasinya.

Notifikasi dan log

Setiap workflow diakhiri langkah Slack yang memposting sukses atau gagal ke channel deploy saat secret repository SLACK_WEBHOOK_URL diset; tanpa itu langkahnya tidak berbuat apa-apa. Setiap eksekusi menyimpan log-nya di tab Actions repository dan bisa dijalankan ulang: skripnya idempoten, dan eksekusi tanpa hal baru untuk disinkronkan menemukan .sync-state sudah mutakhir dan tidak berbuat apa-apa.

Mirror INARTS

Setiap push plain dan terenkripsi juga pergi ke GitLab INARTS, dengan nama yang dipakai INARTS (inact-timas-rekind untuk JOTRE, inact-kso-timas untuk KTP). Untuk Timas dan JOTRE salinan INARTS-lah yang ditarik produksi. Medco hanya push twin terenkripsi ke sana. Job QA master di kedua box me-mirror main ke INARTS dan memperlakukan balapan "cannot lock ref" di antara keduanya sebagai sukses.

Hal yang perlu diwaspadai

  • staging di Medco dan JOTRE tidak deploy ke mana pun. Branch-nya ada; workflow mengabaikannya.
  • Twin terenkripsi bukan mirror. File yang dilindungi berbeda secara sengaja, dan path yang diabaikan tidak pernah sampai. Jangan diff kedua repository dan "memperbaiki" perbedaannya.
  • Sinkronisasi yang terblokir tidak terlihat oleh developer. Cari .sync-blocked di workspace deployer saat push tidak sampai ke QA.
  • Runner Tomori harus berjalan sebagai akun yang punya kunci SSH INARTS. Disiapkan 2026-09-01; kalau service-nya dikembalikan ke NETWORK SERVICE, pull-nya gagal.