Belajar k6 - k6 di CI/CD dan Workflow Otomasi
Series/Belajar k6/Episode 16
Episode 16 of 19

Belajar k6 - k6 di CI/CD dan Workflow Otomasi

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.

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

Pendahuluan

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.

Mengapa k6 Harus Masuk Pipeline

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:

  • Mendeteksi regresi performa lebih awal. Bug yang membuat p95 melonjak dua kali lipat bisa muncul dua minggu setelah merge, dan saat itu memisahkan penyebab dari sekian banyak perubahan lain jauh lebih sulit. Di pipeline, regresi terdeteksi pada hari ia lahir.
  • Environment yang konsisten. Runner CI adalah mesin bersih — hasil test tidak dipengaruhi oleh aplikasi lain yang kebetulan berjalan di laptop kalian.
  • Performa menjadi keputusan, bukan opini. Threshold yang dilanggar berarti build gagal. Tidak ada negosiasi: angka berbicara.

Exit Code: Bahasa Universal Hasil Test

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 codeArtiAksi CI
0Test selesai, semua threshold terpenuhiLanjut ke tahap berikutnya
1Error umum: file tidak ditemukan, eksekusi gagalPerbaiki setup dan skrip
99Satu atau lebih threshold dilanggarGagalkan build dan unggah laporan
107Exception di dalam skripPerbaiki 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: grafana/k6-action@v0.3.1

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:

.github/workflows/load-test.yml
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.json

Ada 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:

Menjalankan k6 via image resmi di CI
docker run --rm -i grafana/k6 run - < script.js

Pola 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.

GitLab CI: image loadimpact/k6

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:

.gitlab-ci.yml
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 days

Ketika 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.

Jenkins (Selayang Pandang)

Di Jenkins, pola yang sama diungkapkan dalam Jenkinsfile. Pipeline declarative berikut menjalankan k6 di dalam kontainer Docker dan mengarsipkan laporan:

JenkinsJenkinsfile
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.

Strategi: Smoke Test di Merge Request, Load Test di Release

Menjalankan semua jenis test di semua tahap adalah pemborosan CI minutes dan membuat tim enggan mengubah pipeline. Distribusikan beban sesuai frekuensi dan biaya:

  • Setiap merge request / pull requestsmoke test singkat (beberapa VU, 1-2 menit). Tujuannya: memvalidasi skrip tetap berjalan dan menangkap regresi kasar dengan cepat.
  • Merge ke main atau stagingload test kecil dengan beban moderat untuk memastikan integrasi lintas fitur tidak merusak performa.
  • Menjelang releaseload test penuh dengan beban dan durasi produksi, dijalankan sebagai gate terakhir sebelum deploy.
  • Terjadwal (misalnya nightly)soak test untuk mendeteksi degradasi yang muncul perlahan.

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 Umum di CI/CD

KesalahanDampakPerbaikan
Tidak mengunggah artifact dengan when: alwaysLaporan hilang saat build gagalUnggah laporan dalam blok selalu
Load test penuh di setiap PRCI lambat dan mahal, tim menghindari testPangkas jadi smoke test di PR
Mencampur 99 dan 107Salah diagnosis: sistem vs skripBaca exit code sebelum menyalahkan
Threshold terlalu ketat sampai flakyTim mematikan test secara sepihakJaga flake lewat retry (episode 15)
Runner dengan resource tidak stabilHasil tidak reproducibleKunci type runner atau mesin CI

Penutup

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!

Belajar k6 - k6 di CI/CD dan Workflow Otomasi | Belajar k6