CI/CD dengan GitHub Actions: Dari Nol Hingga Produksi

Foto oleh Unsplash

Foto oleh Unsplash
CI/CD dengan GitHub Actions telah menjadi standar de-facto untuk merilis software secara andal dan cepat. Baik Anda developer solo maupun bagian dari tim engineering yang berkembang, mengotomasi tahap pengujian, build, dan deployment menghilangkan langkah manual yang melelahkan antara sebuah commit dan rilis yang live. Dalam panduan ini kita akan membangun pipeline siap produksi dari nol — mencakup workflow, penerbitan Docker image, deployment via SSH, dan praktik keamanan terbaik.
Continuous Integration (CI) adalah praktik menjalankan pengujian secara otomatis setiap kali kode di-push. Continuous Deployment (CD) melangkah lebih jauh dengan mengirimkan build yang lolos secara otomatis ke environment staging atau produksi. GitHub Actions mengimplementasikan keduanya langsung di dalam repository menggunakan file workflow YAML yang disimpan di bawah .github/workflows/.
Setiap workflow GitHub Actions diawali dengan trigger (on:), mendefinisikan satu atau lebih job, dan setiap job berisi rangkaian langkah. Langkah-langkah dapat berupa perintah shell atau marketplace action yang dapat digunakan kembali yang diterbitkan oleh komunitas. Job berjalan di virtual machine yang disebut runner — GitHub menyediakan runner Ubuntu, Windows, dan macOS yang di-hosting secara gratis dalam kuota bulanan.
Workflow dapat dipicu oleh puluhan event: push, pull_request, schedule (cron), workflow_dispatch (manual), atau repository_dispatch (webhook eksternal). Menggunakan filter branch seperti 'branches: [main]' memastikan job deployment produksi Anda hanya berjalan ketika kode masuk ke branch main, bukan branch fitur.
Simpan semua kredensial di GitHub Encrypted Secrets (Settings → Secrets and variables → Actions) dan jangan pernah meng-hardcode token atau password dalam file workflow. Secret secara otomatis disembunyikan di log.
Pipeline CI yang kuat membangun dan menandai Docker image pada setiap test run yang berhasil, kemudian mendorongnya ke container registry. Menggunakan docker/build-push-action bersama Docker Buildx memungkinkan fitur canggih seperti multi-platform build dan layer caching inline, yang secara drastis mengurangi waktu build pada run berikutnya.
Workflow di bawah ini merangkai tiga job menggunakan kata kunci needs: untuk memastikan eksekusi berurutan. Test harus lulus sebelum image dibangun, dan image harus diterbitkan sebelum perintah SSH deployment berjalan. Ini memastikan kode yang rusak tidak pernah mencapai produksi.
name: CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm test
build-and-push:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
push: true
tags: myuser/myapp:latest,myuser/myapp:${{ github.sha }}
deploy:
needs: build-and-push
runs-on: ubuntu-latest
steps:
- name: Deploy to production
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.PROD_HOST }}
username: deploy
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
docker pull myuser/myapp:latest
docker stop myapp || true
docker rm myapp || true
docker run -d --name myapp -p 3000:3000 myuser/myapp:latestCache langkah npm ci install menggunakan actions/cache atau opsi cache: bawaan pada actions/setup-node. Untuk Docker, masukkan cache-from: type=registry ke docker/build-push-action agar layer yang tidak berubah diambil dari registry daripada dibangun ulang. Pada cache yang sudah hangat, waktu build turun dari beberapa menit menjadi di bawah 30 detik.
Langkah deployment yang menghentikan container yang berjalan sebelum memulai yang baru menciptakan jendela gangguan singkat. Dua pola sederhana menghindari ini: menggunakan kebijakan rolling update start-first Docker, atau menjalankan container baru sementara di port berbeda sebelum mengalihkan aturan load balancer.
Marketplace action appleboy/ssh-action memungkinkan Anda menjalankan perintah shell pada server remote melalui SSH tanpa memasang agen apa pun. Setelah menarik dan memulai container baru, tambahkan loop health check yang mem-poll endpoint /health dengan timeout sebelum menyatakan deployment berhasil.
Hindari menampilkan variabel environment atau mencetak output debug yang mungkin berisi secret. Gunakan kondisi 'if: failure()' untuk mengunggah artefak debug hanya ketika job gagal, menjaga log tetap bersih dalam run normal. Segera rotasi secret apa pun yang tidak sengaja tercatat di log.
Pipeline yang menangani kredensial produksi adalah target bernilai tinggi. Kunci izin di level workflow dan job, pin action pihak ketiga ke commit SHA tertentu daripada tag yang dapat berubah, dan aktifkan required status checks agar branch main hanya dapat menerima kode melalui pull request yang telah direview.
Menggunakan 'actions/checkout@v4' mereferensikan tag yang dapat berubah. Seseorang dengan akses write ke repository tersebut dapat mengubah ke mana v4 mengarah. Mem-pin ke commit SHA penuh — 'actions/checkout@11bd719' — memastikan Anda selalu mendapatkan kode yang telah Anda review, menghilangkan risiko supply-chain.
Penyedia OIDC GitHub memungkinkan workflow Anda meminta JWT berumur pendek yang dipercaya langsung oleh penyedia cloud (AWS, GCP, Azure). Anda mengkonfigurasi trust policy di sisi cloud, lalu tidak ada secret statis yang tersimpan di repository Anda sama sekali — workflow menukar token OIDC dengan kredensial sementara saat runtime.
Strategi matrix GitHub Actions memungkinkan Anda menjalankan job yang sama di berbagai versi runtime, sistem operasi, atau variabel kustom secara paralel. Untuk proyek Node.js Anda mungkin menguji di Node 18, 20, dan 22 secara bersamaan, memotong total waktu CI hingga dua pertiga dibandingkan run berurutan.
Definisikan matrix dengan 'node-version: [18, 20, 22]' dan referensikan sebagai '${{ matrix.node-version }}' di dalam langkah setup-node. GitHub secara otomatis memfanout job ke tiga runner paralel. Jika salah satu versi gagal, pemeriksaan keseluruhan ditandai gagal, memberi Anda sinyal tepat tentang kompatibilitas.
Gunakan 'continue-on-error: true' pada leg matrix individual ketika Anda ingin mengumpulkan data dari versi Node eksperimental tanpa memblokir merge. Tambahkan langkah ringkasan akhir yang membaca outcome matrix dan memposting tabel Markdown ke PR sebagai komentar menggunakan GitHub API.
Untuk memaksimalkan GitHub Actions, penting memahami istilah-istilah kunci: workflow trigger, job, marketplace action, repository secret, and runner.