Kemampuan yang Harus Dimiliki Pipeline CI/CD (Melampaui Hype)

Anda push kode, pipeline berubah hijau, dan deployment berjalan. Namun saat terjadi masalah, Anda sadar pipeline tidak pernah dirancang untuk menanganinya. Migrasi database berjalan dalam urutan yang salah. Artifact dari staging berbeda dengan yang dideploy ke production. Dan rollback? Tidak ada yang merencanakannya.

Inilah celah antara memiliki pipeline dan memiliki pipeline yang benar-benar bekerja. Tools seperti Jenkins, GitHub Actions, GitLab CI, atau ArgoCD semuanya mengklaim dapat menyelesaikan delivery, tetapi tool itu sendiri bukanlah masalahnya. Masalahnya adalah kemampuan yang hilang. Jika pipeline Anda tidak memiliki blok bangunan yang tepat, tidak ada tool yang bisa memperbaikinya.

Berikut adalah enam kemampuan fundamental yang harus dimiliki setiap pipeline CI/CD. Bukan nice-to-have. Bukan fitur yang ditambahkan saat ada waktu luang. Ini adalah persyaratan minimum untuk membawa perubahan dari kode ke production dengan aman.

Build: Ubah Kode Menjadi Sesuatu yang Dapat Dijalankan

Setiap kali developer melakukan push perubahan, pipeline harus mengonversi kode tersebut menjadi sesuatu yang benar-benar bisa dijalankan. Untuk bahasa yang dikompilasi seperti Go, Rust, atau Java, ini berarti mengompilasi source code menjadi binary. Untuk bahasa interpretasi seperti Python atau JavaScript, build berarti memeriksa sintaks, menggabungkan modul, menyelesaikan dependensi, dan menyiapkan lingkungan runtime.

Build adalah gerbang pertama. Jika kode tidak bisa di-build, tidak ada hal lain yang penting. Pipeline harus gagal cepat di sini, jangan buang waktu menjalankan tes pada kode yang bahkan tidak bisa dikompilasi.

Kesalahan umum adalah menganggap build sebagai langkah sederhana yang selalu berhasil. Namun lingkungan build berbeda. Build yang berhasil di laptop developer mungkin gagal di pipeline karena library sistem yang hilang, versi tool yang berbeda, atau variabel lingkungan. Langkah build di pipeline harus reproducible dan terisolasi, sehingga apa yang berhasil di CI berhasil di mana pun.

Test: Tangkap Masalah Sebelum Sampai ke Pengguna

Setelah build berhasil, pipeline harus menjalankan tes otomatis. Ini bukan hanya tentang unit test yang berjalan dalam milidetik. Pipeline yang sehat menjalankan beberapa lapisan pengujian:

  • Unit test yang memverifikasi perilaku individual
  • Integration test yang memeriksa bagaimana komponen bekerja bersama
  • End-to-end test yang mensimulasikan skenario pengguna nyata

Setiap lapisan menangkap jenis masalah yang berbeda. Unit test menangkap kesalahan logika. Integration test menangkap ketidakcocokan antar layanan. End-to-end test menangkap kegagalan alur kerja yang melintasi beberapa sistem.

Kuncinya adalah otomatisasi. Tes harus berjalan tanpa campur tangan manusia. Jika seseorang harus memicu tes secara manual atau menginterpretasikan hasil, pipeline kehilangan nilai utamanya: kecepatan dan konsistensi. Setiap tes yang berjalan otomatis berarti satu hal yang tidak perlu diingat manusia untuk diperiksa.

Package: Buat Artifact yang Versi dan Siap Deploy

Setelah kode di-build dan tes lulus, pipeline harus mengemas hasilnya menjadi artifact yang bisa dideploy. Format artifact tergantung pada apa yang Anda kirim:

  • Container image untuk microservices
  • File binary untuk aplikasi desktop
  • APK atau IPA untuk aplikasi mobile
  • Arsip zip untuk serverless functions
  • Helm chart untuk deployment Kubernetes

Setiap artifact harus memiliki versi unik. Bukan sekadar timestamp atau nomor build, tetapi versi yang terhubung kembali ke commit yang tepat, pipeline run, dan hasil tes. Ketertelusuran inilah yang memungkinkan Anda tahu persis apa yang berjalan di production dan apa yang berubah antar versi.

Artifact harus disimpan di registry atau repositori pusat yang dapat diakses oleh tahap deployment. Jika Anda membangun ulang artifact pada saat deploy, Anda kehilangan konsistensi. Artifact yang lulus tes harus persis artifact yang sama yang dideploy.

Deploy: Tempatkan Artifact di Lingkungan Target

Deployment lebih dari sekadar menyalin file. Ini adalah proses menempatkan versi baru ke dalam lingkungan dan membuatnya melayani traffic. Untuk staging, deployment berarti menginstal versi baru untuk pengujian. Untuk production, berarti mengganti versi yang berjalan tanpa mengganggu pengguna.

Ada berbagai strategi deployment untuk tingkat risiko yang berbeda:

  • Rolling update: mengganti instance satu per satu
  • Blue-green: mengalihkan traffic antara dua lingkungan yang identik
  • Canary: mengirim persentase kecil traffic ke versi baru terlebih dahulu
  • Feature flags: deploy kode tetapi tetap disembunyikan di balik toggle

Pipeline harus mendukung strategi yang tepat untuk setiap lingkungan. Staging bisa menggunakan penggantian sederhana. Production sering membutuhkan peluncuran bertahap dengan monitoring. Pipeline harus mengotomatiskan seluruh proses, bukan hanya penyalinan file.

Migrate: Tangani Perubahan Database dengan Aman

Jika aplikasi Anda menggunakan database, pipeline harus menangani migrasi skema. Menambahkan kolom, mengubah tipe data, atau membuat tabel baru memerlukan menjalankan skrip migrasi dalam urutan tertentu. Migrasi ini tidak boleh dicampur secara acak dengan deployment aplikasi.

Bagian yang rumit adalah pengurutan. Terkadang migrasi harus berjalan sebelum kode aplikasi baru dideploy. Misalnya, menambahkan kolom nullable yang akan digunakan oleh kode baru. Di lain waktu, migrasi harus berjalan setelah kode baru dideploy. Misalnya, menghapus kolom lama yang masih direferensikan oleh kode lama.

Pipeline harus mengetahui urutan ini dan menjalankannya dengan benar. Migrasi yang berjalan pada waktu yang salah dapat menyebabkan downtime, kehilangan data, atau keduanya. Ini adalah salah satu kemampuan yang paling sering diabaikan dalam pipeline CI/CD, dan salah satu yang paling berbahaya jika salah.

Rollback: Batalkan Saat Terjadi Masalah

Tidak semua deployment berhasil. Ketika versi baru menyebabkan error, degradasi performa, atau korupsi data, pipeline harus bisa kembali ke versi sebelumnya. Rollback bukan sekadar mendeploy ulang artifact lama. Ini melibatkan:

  • Mengembalikan aplikasi ke versi sebelumnya
  • Menjalankan reverse migration pada database
  • Mengembalikan konfigurasi infrastruktur
  • Memverifikasi bahwa rollback benar-benar berhasil

Rollback harus direncanakan sebelum deployment pertama. Jika Anda mendesain pipeline tanpa mempertimbangkan cara membatalkan perubahan, Anda akan mendapati diri Anda tergesa-gesa menulis skrip rollback saat production down. Itu adalah waktu terburuk untuk memikirkannya.

Untuk migrasi database, rollback berarti memiliki down migration yang membalikkan up migration. Untuk infrastruktur, berarti menyimpan file state sebelumnya atau menggunakan tools infrastructure-as-code yang mendukung rollback state. Untuk aplikasi, berarti menyimpan artifact sebelumnya dan memiliki strategi deployment yang mendukung perpindahan instan.

Menyatukan Semuanya

Keenam kemampuan ini — build, test, package, deploy, migrate, dan rollback — membentuk fondasi dari setiap pipeline CI/CD yang sesungguhnya. Tergantung pada apa yang Anda kirim, beberapa kemampuan mungkin terlihat berbeda. Pipeline infrastruktur mungkin mengganti build dan package dengan validasi konfigurasi dan persiapan state. Pipeline mobile mungkin menambahkan code signing dan pengiriman ke app store. Namun fungsi intinya tetap sama.

Berikut adalah pipeline GitLab CI minimal yang memetakan setiap kemampuan ke sebuah stage:

stages:
  - build
  - test
  - package
  - deploy
  - migrate
  - rollback

build:
  stage: build
  script:
    - go build -o app

test:
  stage: test
  script:
    - go test ./...

package:
  stage: package
  script:
    - docker build -t myapp:$CI_COMMIT_SHA .
    - docker push registry.example.com/myapp:$CI_COMMIT_SHA

deploy:
  stage: deploy
  script:
    - kubectl set image deployment/myapp myapp=registry.example.com/myapp:$CI_COMMIT_SHA

migrate:
  stage: migrate
  script:
    - ./run_migrations up

rollback:
  stage: rollback
  script:
    - ./run_migrations down
    - kubectl rollout undo deployment/myapp
  when: manual

Diagram alur berikut menunjukkan bagaimana keenam kemampuan ini terhubung dalam pipeline tipikal:

flowchart TD A[Push Kode] --> B[Build] B --> C[Test] C --> D{Package} D --> E[Deploy] E --> F[Migrate DB] F --> G{Health Check} G -- Lulus --> H[Selesai] G -- Gagal --> I[Rollback] I --> J[Restore DB] J --> K[Deploy Ulang Versi Sebelumnya] K --> L[Verifikasi]

Sebelum Anda memilih tool CI/CD atau mendesain ulang pipeline, petakan kemampuan mana yang sudah Anda miliki dan mana yang hilang. Tool yang menjanjikan segalanya tetapi tidak menangani migrasi database atau perencanaan rollback akan membuat Anda terekspos.

Daftar Periksa Kemampuan Cepat

  • Build berjalan di lingkungan yang terisolasi dan reproducible
  • Tes berjalan otomatis di berbagai level
  • Artifact memiliki versi dan disimpan di registry pusat
  • Deployment mendukung strategi yang tepat untuk setiap lingkungan
  • Migrasi database diurutkan dengan benar relatif terhadap deployment aplikasi
  • Rollback teruji dan berfungsi untuk aplikasi, database, dan infrastruktur

Intisari Konkret

Pipeline bukanlah kumpulan langkah. Pipeline adalah sistem yang harus menangani siklus hidup penuh sebuah perubahan: dari kode ke layanan yang berjalan, dan kembali lagi jika diperlukan. Jika pipeline Anda tidak bisa build, test, package, deploy, migrate, dan rollback, maka pipeline tersebut tidak lengkap. Mulailah dengan mengisi kemampuan yang hilang, bukan dengan mengganti tool.