Memasukkan k6 ke pipeline otomasi dengan GitHub Actions, GitLab CI, dan Jenkins, memahami exit code k6 sebagai bahasa universal hasil test, memanfaatkan artifact laporan, serta menyusun strategi smoke test di setiap merge request dan load test penuh di release.

Pada episode 15, kalian belajar menangani degradasi secara terukur: membedakan flake dari fail, menulis retry dengan backoff, dan membedah akar masalah dari breakdown metrik. Seluruh keterampilan itu, betapapun canggih, hanya bernilai jika dijalankan secara otomatis. Test yang dijalankan manual di laptop tidak melindungi apa pun — hasilnya tersimpan di terminal, bukan menjadi keputusan.
Episode 16 mengubah posisi k6 dari alat diagnostik menjadi pengawas pipeline: skrip kalian dijalankan otomatis oleh CI/CD pada setiap merge request dan setiap release, dan kegagalan performa menghentikan proses sebelum merugikan pengguna. Kita bahas GitHub Actions, GitLab CI, dan Jenkins, serta bahasa universal yang menghubungkan k6 dengan semuanya: exit code.
Anggap k6 sebagai satpam di pintu gerbang. Kalau satpam hanya berjaga saat ada orang yang mengingatkannya, banyak tamu tak diundang akan masuk. Pipeline adalah penjagaan yang konsisten: setiap perubahan kode melewati gerbang yang sama, dengan standar yang sama, tanpa bergantung pada ingatan manusia.
Tiga alasan kuat memasukkan k6 ke CI/CD:
k6 mengakhiri prosesnya dengan exit code yang bisa dibaca oleh CI mana pun. Karena semua pipeline menentukan sukses atau gagal dari exit code step, tanpa satu baris skrip tambahan pun threshold yang dilanggar akan menggagalkan build:
| Exit code | Arti | Aksi CI |
|---|---|---|
0 | Test selesai, semua threshold terpenuhi | Lanjut ke tahap berikutnya |
1 | Error umum: file tidak ditemukan, eksekusi gagal | Perbaiki setup dan skrip |
99 | Satu atau lebih threshold dilanggar | Gagalkan build dan unggah laporan |
107 | Exception di dalam skrip | Perbaiki bug pada skrip |
Perhatikan 107 dan 99: keduanya membuat build gagal, tapi artinya berbeda. 107 menandakan skrip kalian yang rusak — perbaiki sebelum melanjutkan. 99 menandakan sistem yang diuji tidak memenuhi target performa — ini justru informasi yang berharga, karena ia adalah hasil keputusan, bukan bug.
GitHub Actions adalah pilihan paling umum untuk repositori yang sudah tinggal di GitHub. Ekosistemnya menyediakan action resmi grafana/k6-action@v0.3.1 yang membungkus k6: kalian cukup menunjuk file skrip dan action menjalankan k6 run script.js, lalu meneruskan exit code (termasuk 99) sehingga threshold yang gagal otomatis menggagalkan job. Contoh workflow yang menjalankan smoke test pada setiap pull request dan mengunggah laporan:
name: Performance Smoke Test
on:
pull_request:
paths:
- 'api/**'
- 'tests/load/**'
jobs:
smoke:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run k6 smoke test
uses: grafana/k6-action@v0.3.1
with:
filename: ./tests/load/smoke.js
flags: --out json=reports/smoke.json
- name: Upload k6 report
uses: actions/upload-artifact@v4
if: always()
with:
name: k6-report
path: reports/smoke.jsonAda dua detail penting. Pertama, with.filename menunjuk skrip relatif terhadap root repo; flags bisa diisi apa pun yang biasanya kalian berikan ke k6 run — termasuk --out untuk menyimpan hasil JSON. Kedua, if: always() pada step upload memastikan laporan tetap diunggah meski build gagal — justru saat paling dibutuhkan untuk debugging. Tanpa itu, laporan hilang di runner yang sudah dibuang.
Jika tim kalian tidak ingin menambah dependency action, k6 bisa dijalankan langsung lewat image resmi:
docker run --rm -i grafana/k6 run - < script.jsPola run - membaca skrip dari stdin sehingga tidak perlu me-mount file — ringkas untuk satu skrip, meskipun me-mount folder lebih praktis saat skrip bergantung pada file lain.
Di GitLab CI, konsepnya sama, hanya bentuknya berupa jobs dalam .gitlab-ci.yml. Image loadimpact/k6 (nama lama yang tetap dipublikasikan untuk kompatibilitas; image grafana/k6 juga bisa dipakai) sudah berisi binary k6, jadi script cukup memanggil perintah k6 run script.js:
stages:
- test
load-test:
stage: test
image: loadimpact/k6
script:
- k6 run tests/load/smoke.js --out json=results.json
artifacts:
when: always
paths:
- results.json
expire_in: 30 daysKetika threshold dilanggar, k6 run keluar dengan kode 99 dan GitLab menandai job sebagai failed — tidak perlu logika tambahan. Blok artifacts dengan when: always menyimpan laporan JSON meski job gagal, dan expire_in menjaga storage pipeline tetap bersih.
Di Jenkins, pola yang sama diungkapkan dalam Jenkinsfile. Pipeline declarative berikut menjalankan k6 di dalam kontainer Docker dan mengarsipkan laporan:
pipeline {
agent {
docker {
image 'grafana/k6'
}
}
stages {
stage('Load Test') {
steps {
sh 'k6 run tests/load/smoke.js --out json=results.json'
}
}
}
post {
always {
archiveArtifacts artifacts: 'results.json'
}
}
}Saat threshold gagal, step sh menerima exit code 99 dan pipeline berhenti dengan status merah; blok post memastikan laporan diarsipkan baik sukses maupun gagal.
Menjalankan semua jenis test di semua tahap adalah pemborosan CI minutes dan membuat tim enggan mengubah pipeline. Distribusikan beban sesuai frekuensi dan biaya:
main atau staging → load test kecil dengan beban moderat untuk memastikan integrasi lintas fitur tidak merusak performa.Smoke test di PR berfungsi seperti pemeriksaan kopling sebelum balapan: murah, cepat, dan menyaring masalah paling jelas. Load test penuh di release adalah pemeriksaan menyeluruh menjelang start.
| Kesalahan | Dampak | Perbaikan |
|---|---|---|
Tidak mengunggah artifact dengan when: always | Laporan hilang saat build gagal | Unggah laporan dalam blok selalu |
| Load test penuh di setiap PR | CI lambat dan mahal, tim menghindari test | Pangkas jadi smoke test di PR |
Mencampur 99 dan 107 | Salah diagnosis: sistem vs skrip | Baca exit code sebelum menyalahkan |
| Threshold terlalu ketat sampai flaky | Tim mematikan test secara sepihak | Jaga flake lewat retry (episode 15) |
| Runner dengan resource tidak stabil | Hasil tidak reproducible | Kunci type runner atau mesin CI |
Episode 16 menutup lingkaran yang mulai kalian gambar di episode 15: hasil test tidak lagi berhenti di terminal, tetapi menjadi gate otomatis di GitHub Actions, GitLab CI, dan Jenkins. Kalian memahami exit code 0, 1, 99, dan 107 sebagai bahasa universal, memanfaatkan artifact untuk menyimpan laporan, dan menyusun strategi bertingkat dari smoke test di PR hingga load test penuh di release.
Namun satu mesin di pipeline hanya mampu membangkitkan beban yang terbatas. Bagaimana bila target kalian adalah ratusan ribu pengguna bersamaan? Di episode 17 kita keluar dari batas mesin tunggal: distributed load testing dan cloud execution dengan k6 Cloud, load zones, dan alternatif self-managed memakai Kubernetes. Sampai jumpa!