GitHub Actions perlahan membunuh tim engineering
(iankduncan.com)- Meski digunakan luas karena CI bawaan di repo, inefisiensi struktural dan pengalaman pengguna yang tidak stabil menurunkan produktivitas developer
- Pemuatan log viewer yang lambat dan browser yang crash, serta sintaks YAML yang rumit dan kesalahan expression menyebabkan debugging berulang
- Karena struktur yang tidak memberi kepemilikan atas resource compute, tool ini menunjukkan batasan dalam performa, skalabilitas, dan kontrol lingkungan
- Dalam upaya mengakali banyak masalah, tim berulang kali berakhir dengan YAML yang kompleks atau skrip Bash raksasa untuk membangun ulang CI itu sendiri
- Sebaliknya, Buildkite menawarkan alternatif CI yang berkelanjutan dalam jangka panjang lewat struktur YAML yang sederhana, agent yang bisa di-self-host, dan pengalaman log yang praktis
Masalah GitHub Actions
- Log viewer GitHub Actions tidak efisien: bahkan untuk memeriksa error sederhana pun diperlukan beberapa tahap klik dan pemuatan halaman
- Saat build gagal, diperlukan 3~4 perpindahan halaman dari halaman ringkasan check → halaman eksekusi workflow → halaman job → klik step yang terlipat, dan setiap tahap memicu loading terpisah
- Pada log build berukuran besar, browser berulang kali crash, dan saat memakai fitur pencarian Chrome bisa macet secara konsisten
- Pada log yang panjang, scroll bahkan tidak berfungsi, sehingga pada akhirnya perlu mengunduh artifact log mentah lalu membukanya di text editor
- Tombol back membawa pengguna bukan ke halaman PR semula, melainkan ke halaman UI GitHub Actions yang tidak dapat diprediksi, dan riwayat browser pun penuh dengan URL Actions
- Proses debugging yang tidak produktif
- Untuk memeriksa environment variable, developer menambahkan step
run: envlalu push ulang, yang menghasilkan feedback loop selama 20 menit, dan proses ini bisa terulang belasan kali hanya untuk perubahan satu baris - Feedback loop 20 menit ini terus berulang hingga satu hari kerja habis hanya untuk menunggu CI
- Untuk memeriksa environment variable, developer menambahkan step
- Batasan struktural YAML
- YAML GitHub Actions adalah bentuk khusus yang menggabungkan bahasa expression miliknya sendiri, model objek context, dan aturan interpolasi string
- Jika salah memakai satu tanda kutip di expression
${{ }}, Anda baru menyadari string hilang setelah menunggu 4 menit sampai runner selesai spin-up - Sintaks expression berada di ruang batas (liminal space): terlalu rumit untuk sekadar konfigurasi, tapi terlalu terbatas untuk dianggap bahasa pemrograman sungguhan
- Strukturnya membuat orang mempelajari sintaks bukan dari dokumentasi, melainkan dari pengalaman gagal
- Risiko keamanan Marketplace
- Saat memanggil action eksternal dengan sintaks
uses:, Anda memberikan hak akses ke repository, secret, dan lingkungan build kepada pihak ketiga yang belum tervalidasi - SHA pinning memang dimungkinkan, tetapi hampir tidak ada yang benar-benar melakukannya, dan bahkan jika dipin, Anda tetap menjalankan kode buram yang belum dibaca dengan hak akses
GITHUB_TOKEN - Marketplace mencampur action yang dikelola komunitas dengan kualitas yang beragam, dan sebagian besar terdiri dari skrip shell dan Dockerfile
- Manajemen dependensi tidak transparan dan ada kemungkinan eksekusi kode yang tidak aman
- Saat memanggil action eksternal dengan sintaks
- Keterbatasan lingkungan compute
- Runner default GitHub Actions adalah shared runner milik Microsoft yang lambat, sumber dayanya terbatas, dan tidak memungkinkan kustomisasi yang berarti
- Biaya runner yang lebih besar cukup mahal sampai-sampai memicu permintaan meeting dari tim finance untuk "kita perlu bicara", dan bahkan begitu Anda tetap tidak bisa mengendalikan lingkungannya
- Setidaknya ada 6 startup seperti Namespace, Blacksmith, Actuated, Runs-on, BuildJet yang khusus menyelesaikan masalah lambatnya runner GitHub Actions, yang dengan sendirinya membuktikan lemahnya lingkungan compute bawaan
- Menyiapkan self-hosted runner memang menyelesaikan masalah compute, tetapi masalah lain seperti expression YAML, model permission, Marketplace, dan log viewer tetap ada
Masalah yang detail tetapi terus menumpuk
actions/cache: cache key membingungkan, cache miss terjadi diam-diam, eviction cache tidak transparan, sehingga debugging cache menghabiskan lebih banyak waktu daripada yang dihemat- Reusable workflow: tidak bisa dinesting melewati kedalaman tertentu, tidak bisa mengakses context workflow pemanggil dengan rapi, dan tidak bisa diuji secara terisolasi
- Model permission
GITHUB_TOKEN:permissions: write-allterlalu luas, sementara permission granular menjadi rumit seperti labirin karena interaksi antar pengaturan level repository, workflow, dan job - Kontrol concurrency: membatalkan eksekusi yang sedang berjalan pada branch yang sama bisa dilakukan dalam satu baris, tetapi kontrol yang lebih rinci dari itu tidak didukung
- Secret tidak bisa dipakai dalam kondisi
if: eksekusi kondisional sepertiif: secrets.DEPLOY_KEY != ''tidak dimungkinkan; ini masuk akal dari sisi keamanan, tetapi memerlukan solusi akal-akalan saat menulis workflow yang harus berjalan baik di fork maupun repo utama
Jebakan "pakai skrip Bash saja"
- Engineer yang lelah dengan YAML CI tergoda untuk mengganti semuanya dengan skrip bash di
run:, tetapi seiring waktu skrip itu mulai bertambah dengan conditional, function, parsing argumen, dan parallel processing - Tiga bulan kemudian, Anda memiliki 800 baris bash yang mengimplementasikan ulang paralelisasi job dengan
waitdan file PID, lengkap dengan logika retry dan parsing output buatan sendiri - Pada akhirnya Anda bukan keluar dari sistem CI, melainkan membangun sendiri sistem CI yang lebih buruk dalam bash, tanpa framework pengujian dan tanpa ada yang bisa mengikutinya
- Bash cocok sebagai glue, tetapi jika dipakai sebagai build system atau test harness, hasilnya adalah memindahkan kompleksitas dari tempat yang punya guardrail ke tempat yang tidak punya
Pendekatan alternatif Buildkite
-
Log viewer yang stabil
- Log viewer Buildkite menampilkan log dengan benar tanpa membuat browser crash, dan ANSI color serta formatting dari test framework dirender apa adanya
- Dengan fitur Annotation, build step bisa langsung mencetak ringkasan kegagalan test, laporan coverage, atau tautan deployment dalam Markdown ke halaman build
- Karena agent berjalan di infrastruktur sendiri, Anda bisa masuk ke mesin build lewat SSH untuk melakukan debugging langsung
-
Struktur YAML yang sederhana
- YAML Buildkite adalah struktur data murni untuk mendeskripsikan pipeline, yang hanya mendeklarasikan step, command, dan plugin
- Jika butuh logika nyata, tulislah skrip dalam bahasa pemrograman sungguhan yang bisa dijalankan secara lokal
- Ia menjaga dengan jelas batas "orkestrasi ada di konfigurasi, logika ada di kode", yaitu batas yang justru diburamkan oleh GitHub Actions
-
Kontrol penuh atas lingkungan compute
- Agent Buildkite adalah binary tunggal yang bisa dijalankan di cloud sendiri, on-premises, atau hardware kustom mana pun
- Anda bisa mengendalikan sepenuhnya instance type, caching, local storage, dan network, mulai dari instance EC2 besar dengan drive NVMe dan Docker layer cache 20GB hingga Raspberry Pi
- Tidak ada industri pihak ketiga bertema "Buildkite tapi lebih cepat"; Anda cukup menjalankan mesin yang lebih besar
- Untuk maintainer individu yang mengelola library open source kecil, free tier GitHub Actions untuk public repo tetap bernilai
- Sasaran utama tulisan ini adalah tim yang mengoperasikan sistem produksi, di mana waktu CI diukur sebagai hilangnya jam engineering per minggu dan build 45 menit menimbulkan biaya baik dari sisi compute maupun tenaga kerja
- Dalam lingkungan seperti itu, overhead menjalankan agent Buildkite akan cepat balik modal
-
Dukungan pipeline dinamis
- Di Buildkite, step pipeline adalah data, dan skrip bisa menghasilkan step tambahan secara dinamis saat runtime lalu mengunggahnya
- Di monorepo, pendekatan ini memungkinkan membuat hanya step build dan test yang benar-benar diperlukan berdasarkan file yang berubah, tanpa matrix yang di-hardcode atau spaghetti
if: contains(...) matrix, kondisiif, dan reusable workflow di GitHub Actions mencoba mengaproksimasi ini, tetapi akhirnya membuat mesin Rube Goldberg dalam bahasa deklaratif yang daya ekspresinya kurang
-
Kesederhanaan struktur plugin
- Secara struktur, ini mirip dengan GitHub Actions Marketplace karena sama-sama mengambil kode dari repo pihak ketiga
- Bedanya, plugin Buildkite umumnya bukan Docker image melainkan thin shell hook yang permukaannya kecil dan bisa dibaca seluruhnya dalam hitungan menit
- Karena berjalan di infrastruktur Anda sendiri, blast radius-nya bisa Anda kendalikan
-
Fitur detail yang berfokus pada pengalaman pengguna
- Buildkite memungkinkan menampilkan emoji kustom (
:parrot:,:docker:dan lain-lain) di samping step pipeline; ini tampak sepele, tetapi menunjukkan perhatian detail terhadap pengalaman memakai produk - GitHub Actions terasa seperti hasil rancangan komite yang tidak pernah sekali pun bertanya, "apakah ini menyenangkan untuk dipakai?"
- Buildkite memungkinkan menampilkan emoji kustom (
Kesimpulan: kriteria memilih sistem CI
- GitHub Actions menguasai pasar karena keunggulan sebagai default bawaan, gratis untuk public repo, terintegrasi di platform yang sudah dipakai semua orang, dan berada pada level "cukup baik (Good Enough)"
- Ia seperti Internet Explorer-nya CI; orang tetap memakainya karena biaya pindah itu nyata dan waktu itu terbatas
- Buildkite lebih unggul dalam hal keberlanjutan penggunaan dan pengalaman developer
- Untuk proyek open source sederhana, GitHub Actions sudah cukup, tetapi untuk lingkungan produksi berskala besar, Buildkite lebih cocok
- Dalam sejarah sistem CI, yang meraih pangsa pasar bukanlah sistem terbaik, melainkan sistem yang paling mudah untuk mulai dipakai
- GitHub Actions adalah CI yang paling mudah untuk memulai, sedangkan Buildkite adalah CI yang paling baik untuk terus digunakan; dalam jangka panjang, yang kedua lebih penting
- Jika alat CI dibangun dengan struktur yang menghabiskan waktu developer, maka masalahnya bukan pada developernya, melainkan pada alat itu sendiri
3 komentar
Sepertinya masalahnya adalah CI itu sendiri jadi semakin kompleks.
Sepertinya tulisan yang sama terunggah dua kali. Tapi belakangan ini kombinasi seperti ini tampaknya cukup cocok untuk dirangkai oleh AI..
Komentar Hacker News
Saya sudah memakai beberapa sistem CI. Saya banyak memakai CircleCI dan GitHub Actions, tapi kesimpulan saya berbeda dari penulis
Dulu Jenkins itu khusus Java dan Travis khusus Rails, tetapi CI yang sangat terspesialisasi seperti itu pada akhirnya jalan buntu. Sekarang CI telah berevolusi menjadi sekadar orkestrator workflow
Alasan saya pindah dari CircleCI 2 ke GitHub Actions juga karena CircleCI gagal menangani transisi ini dengan baik. GHA cukup ekspresif
Hal seperti browser log atau sintaks YAML itu masalah kecil. Yang penting adalah kepemilikan sumber daya komputasi dan pipeline dinamis, yang pertama bisa dilakukan di semua CI dan yang kedua adalah keunggulan Buildkite
Kesimpulan saya, Actions secara praktik cukup bagus, dan kalau saya memulai perusahaan baru saya akan memakai Buildkite, sedangkan untuk open source saya akan memakai Actions
Kalau tidak memahami graf build, Anda harus mempertahankan status incremental build, dan itu memicu bug sementara/intermiten. Karena itu dibutuhkan sistem yang memahami struktur build secara mendalam seperti UnrealEngine Horde atau UBA
Kalau memakai CI yang digeneralisasi, build bisa memakan waktu lebih dari sehari
Saya cenderung hanya memakai bagian GHA yang bagus. Misalnya, GitHub sangat bagus sebagai dispatcher event tetapi kurang bagus sebagai orkestrator workflow, jadi bagian itu saya delegasikan ke sistem lain
Kalau log yang dilihat puluhan kali sehari terasa tidak nyaman, produktivitas turun. Membaca log mentah sambil mengabaikan escape code benar-benar menyiksa
Saya menjaga semuanya tetap sederhana. Semua orkestrasi saya taruh di skrip deploy.sh dan dijalankan di Mac lokal atau AWS CodeBuild
YAML-nya cuma satu baris,
bash deploy.sh. Asalkan ada container Docker, hasilnya berjalan sama di Azure, GitHub Actions, dan tempat lainStrategi inti di semua lingkungan CI adalah memiliki sistem build yang sama seperti lokal
Saya selalu mulai dari Makefile. Docker, build CI, linting, semuanya dijalankan oleh Makefile. Saat proyek membesar kadang pindah ke alat lain, tetapi dasarnya adalah satu alat pemicu
Saya sering memakai Fastlane di mobile karena mengurangi boilerplate dan memberi struktur. Pada akhirnya itu Ruby, jadi kalau perlu tetap bisa keluar dari sana
(tautan dokumentasi GNU Make)
Pada akhirnya ini seperti berkata “pakai saja skrip Bash”, hanya dengan kompleksitas tambahan yang tidak perlu
Di perusahaan saya sekarang pun, karena pipeline penuh tidak lagi bisa dijalankan secara lokal, muncul infrastruktur CI raksasa yang membuat satu MR diuji dengan menjalankan build sampai 10 kali
Saya merasa tulisan ini seperti iklan Nix/Buildkite
CI seharusnya cukup sampai tingkat menjalankan skrip atau target build. CI hanya menyediakan environment dan konfigurasi, sedangkan logika harus ada di kode
Dengan begitu Anda mendapatkan independensi dari CI, sehingga lebih mudah berpindah antar sistem
GitLab CI cukup bagus dalam menangani kompleksitas seperti ini. Fitur template dan konfigurasi job-nya sangat baik, tetapi debugging sulit dan logika kondisional kadang gagal dengan cara yang tidak terduga
.shmengalami migrasi yang sangat mudahSebaliknya, tim yang memecah semuanya secara rinci di UI malah kesulitan
Masalahnya bukan CI/CD itu sendiri, melainkan budaya memprogram lewat file konfigurasi
Loop
git commit -m "try fix"lalu menunggu 10 menit itu terlalu umum. Lingkungan CI yang bisa direproduksi secara lokal masih sangat kurangKalau isolasi environment ditetapkan sebagai kebijakan, alat apa pun tidak masalah. Pada akhirnya yang penting adalah harmoni antara alat dan metodologi
actsangat membantu untuk mereproduksi CI secara lokalJudul “membunuh tim engineering” itu berlebihan. GitHub Actions itu cukup bagus
Saya lebih memilihnya dibanding Bitbucket atau GitLab
Belakangan ini keandalan GitHub menurun parah
actions/checkoutbisa gagal tanpa alasan, job rilis bisa berjalan dua kali, atau hanya menunggu selama 40 menitSaya sudah memakainya selama bertahun-tahun, tetapi stabilitas dasarnya makin menurun. Menyesal dulu melewatkan Buildkite
GitHub Actions adalah salah satu alat CI terburuk yang pernah saya pakai (setara dengan Jenkins)
Sebaliknya, Buildkite adalah yang terbaik. Berkat pipeline dinamis, saat tes gagal ia bisa otomatis membuat step retry, atau menyesuaikan tes paralel berdasarkan perubahan kode
Kemampuan memakai konfigurasi mesin yang berbeda untuk tiap job CI juga merupakan keunggulan besar. Sangat saya rekomendasikan
Orang yang mendorong “CI sederhana berbasis skrip” tampaknya tidak punya pengalaman pada proyek nyata berskala besar