Apa itu CI/CD — DevOps

Pernah commit kode jam 5 sore Jumat, terus jam 6 dapet error "production down"? Atau dev senior nge-deploy manual lewat SSH terus salah ketik command =…

CI/CD adalah jalur otomatis yang membawa kodemu dari git push sampai jalan di production: kodenya diambil, dipasang, dicek, dibungkus, lalu dikirim, dengan urutan yang sama setiap kali. Bayangin dapur katering. Setiap ada resep baru, masakannya dicicipi dulu, baru dikemas, baru dikirim ke pelanggan. Masakan yang gagal dicicipi gak pernah dikemas, apalagi dikirim. Kalau kurirnya menunggu tanda tangan kepala dapur sebelum berangkat, itu Continuous Delivery. Kalau kurirnya langsung jalan begitu kemasan siap, itu Continuous Deployment.

🧪 Tebakan cepat: commit 7d03b5f membuat test GET /catatan gagal. Apakah image Docker-nya tetap di-build dan dikirim ke web-1? Tebak dulu, jawabannya ada di bagian "Satu step gagal, sisanya berhenti".

Deploy manual: cara yang sudah kita pakai

Sampai sekarang, deploy catatan-api dikerjakan tangan: build image di laptop, push ke registry, lalu SSH ke web-1 dan menjalankan Compose dengan tag baru.

docker build -t ghcr.io/budi/catatan-api:7d03b5f .
docker push ghcr.io/budi/catatan-api:7d03b5f
ssh deploy@web-1 "cd /srv/catatan-api && IMAGE_TAG=7d03b5f docker compose up -d"

Langkahnya benar, tapi gak ada yang memaksa test jalan dulu. Commit 7d03b5f ("urutkan catatan terbaru dulu") salah ketik nama tabel jadi catatn, dan di laptop kamu lupa menjalankan npm test. Setelah deploy, setiap GET /catatan di production menjawab 500, dan log app berisi:

2026-10-09 10:15:02 ERROR relation "catatn" does not exist

Itulah masalah deploy manual: ada langkah yang bisa terlewat, tiap orang bisa beda caranya, dan bug baru ketahuan setelah pengguna kena.

CI: setiap push dicek otomatis

Continuous Integration (CI) artinya setiap push (atau pull request) membuat sebuah server CI mengambil kodenya dan menjalankan pemeriksaan yang sama: pasang dependency, lint, test. Hasilnya tanda hijau (lulus) atau merah (gagal) di commit itu. Disebut "integration" karena tujuannya menggabungkan kode semua orang ke main sesering mungkin, dan itu aman karena setiap gabungan dicek mesin.

CD: yang lulus dikirim

Setelah CI hijau, sisanya membungkus dan mengirim: build image, push ke registry, deploy ke web-1. Huruf D di CD punya dua arti:

Continuous Delivery Continuous Deployment
Otomatis sampai siap deploy, tinggal satu klik production
Deploy ke production menunggu approval manusia langsung, tanpa klik
Cocok untuk tim yang mau memilih jam rilis tim dengan test yang kuat

Keduanya sama-sama CD. Bedanya cuma satu: ada tombol persetujuan sebelum production atau gak.

Pipeline catatan-api

Rangkaian tahap itu disebut pipeline, dan tiap tahapnya step. Ini pipeline catatan-api di Lab, lima step berurutan:

# Nama step Perintah Kategori
1 Install dependencies npm ci build
2 Run ESLint npm run lint lint
3 Run unit tests npm test test
4 Build Docker image docker build lalu docker push build
5 Deploy to web-1 IMAGE_TAG=... docker compose up -d lewat SSH deploy

Kolom kategori dibaca dari kata kunci di nama step, tanpa peduli huruf besar atau kecil, dengan urutan cek tetap:

  1. ada "build", "compile", atau "install": build
  2. ada "lint", "format", atau "style": lint
  3. ada "test", "spec", atau "coverage": test
  4. ada "deploy", "release", atau "publish": deploy
  5. selain itu: other, misalnya "Send Slack notification"

Urutannya penting. "Build and test" kena aturan pertama, jadi build. "Run ESLint" jadi lint, karena "eslint" mengandung "lint".

Satu step gagal, sisanya berhenti

Dua commit di-push berurutan lewat pipeline, dengan Continuous Deployment:

Step a41c9e2 tambah pencarian catatan 7d03b5f urutkan catatan terbaru
Install dependencies lulus, 18 detik lulus, 18 detik
Run ESLint lulus, 6 detik lulus, 6 detik
Run unit tests lulus, 11 detik gagal, 9 detik
Build Docker image lulus, 42 detik dilewati
Deploy to web-1 lulus, 15 detik dilewati
Production di web-1 jadi a41c9e2 tetap a41c9e2

Begitu satu step gagal, step sesudahnya gak dijalankan. Image dari 7d03b5f gak pernah dibuat, apalagi dikirim. Itu jawaban tebakannya. Pengguna tetap memakai a41c9e2 yang sehat, dan yang dapat kabar merah adalah kamu, bukan mereka. Potongan log step test-nya di GitHub Actions:

 FAIL  test/catatan.test.js > GET /catatan > mengembalikan daftar catatan
AssertionError: expected 500 to be 200 // Object.is equality

- Expected
+ Received

- 200
+ 500

 Test Files  1 failed | 2 passed (3)
      Tests  1 failed | 11 passed (12)
Error: Process completed with exit code 1.

Perbaiki typo-nya, push lagi, dan pipeline yang sama membawa perbaikan itu ke production.

Alatnya

Pilihan populer: GitHub Actions (bawaan GitHub, dibahas di pelajaran berikutnya), GitLab CI, Jenkins, dan CircleCI. Semuanya membaca file konfigurasi di repo, jadi pipeline-mu ikut di-review seperti kode. Urutan lint, test, E2E dan branch protection dibahas di pelajaran Testing di CI/CD Pipeline. Cara menjaga secret deploy di pipeline dibahas di CI/CD Pipeline Security.

⚠️ Jebakan yang sering ketemu

TL;DR: CI/CD adalah pipeline otomatis dari push sampai production. CI (Continuous Integration): setiap push otomatis di-install, di-lint, dan di-test, hasilnya hijau atau merah. CD punya dua arti: Continuous Delivery (siap deploy, production menunggu approval manual) dan Continuous Deployment (lulus semua langsung ke production). Pipeline catatan-api: install, lint, test, build image, deploy ke web-1, dan begitu satu step gagal, sisanya dilewati, jadi kode yang test-nya merah gak pernah sampai ke pengguna. Kategori step dibaca dari kata kunci dengan urutan tetap: build, lint, test, deploy, selain itu other. Alat populer: GitHub Actions, GitLab CI, Jenkins, CircleCI.

Yang akan kamu pelajari