CI/CD Laravel dengan GitHub Actions: Test Otomatis hingga Deploy via SSH

Banyak tim kecil masih men-deploy aplikasi dengan cara yang sama: login ke server, git pull, jalankan beberapa perintah artisan, lalu berharap tidak ada yang lupa. Cara ini berjala...

CI/CD Laravel dengan GitHub Actions: Test Otomatis hingga Deploy via SSH

Banyak tim kecil masih men-deploy aplikasi dengan cara yang sama: login ke server, git pull, jalankan beberapa perintah artisan, lalu berharap tidak ada yang lupa. Cara ini berjalan sampai suatu hari ada test yang rusak tetapi tetap naik ke produksi, atau migrasi lupa dijalankan sehingga halaman checkout error selama setengah hari. CI/CD menjadikan langkah-langkah itu otomatis dan selalu sama setiap kali.

Artikel ini membangun pipeline sederhana untuk aplikasi Laravel memakai GitHub Actions: setiap push dan pull request menjalankan test serta pengecekan gaya kode, dan setiap perubahan di branch main yang lulus test otomatis di-deploy ke server lewat SSH.

CI dan CD, Apa Bedanya?

IstilahArtinyaContoh di proyek Laravel
CI (Continuous Integration)Setiap perubahan kode otomatis diujiphp artisan test dan Pint berjalan di setiap push
CD (Continuous Delivery/Deployment)Kode yang lulus uji otomatis disiapkan atau langsung dirilisBranch main yang lulus test otomatis di-deploy ke server

Anda tidak harus langsung menerapkan keduanya. Memulai dengan CI saja sudah memberi manfaat besar, karena kode yang rusak ketahuan sebelum di-merge.

Prasyarat

Langkah 1: Workflow CI untuk Test dan Gaya Kode

Buat file .github/workflows/ci.yml di root repository:

name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Siapkan PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
          extensions: mbstring, pdo_sqlite
          coverage: none

      - name: Cache dependency Composer
        uses: actions/cache@v4
        with:
          path: vendor
          key: composer-${{ hashFiles('composer.lock') }}

      - name: Install dependency
        run: composer install --no-interaction --prefer-dist --no-progress

      - name: Siapkan environment
        run: |
          cp .env.example .env
          php artisan key:generate

      - name: Cek gaya kode
        run: vendor/bin/pint --test

      - name: Jalankan test
        run: php artisan test

Penjelasan bagian-bagian pentingnya:

  • on: workflow berjalan setiap ada push ke main dan setiap pull request.
  • actions/cache: folder vendor disimpan berdasarkan isi composer.lock, sehingga run berikutnya jauh lebih cepat selama dependency tidak berubah.
  • Database test: phpunit.xml bawaan Laravel 11 sudah mengarahkan test ke SQLite in-memory, jadi tidak perlu menyiapkan MySQL. Jika aplikasi Anda memakai fitur khusus MySQL, tambahkan blok services: mysql pada job dan sesuaikan variabel DB_*.
  • pint --test: Laravel Pint (sudah terpasang di proyek Laravel baru) mengecek format kode tanpa mengubahnya, dan gagal bila ada file yang tidak sesuai standar.

Commit dan push file tersebut. Buka tab Actions di repository untuk melihat setiap langkah berjalan beserta log-nya.

Langkah 2: Wajibkan CI Lulus Sebelum Merge

CI hanya berguna jika hasilnya dihormati. Di Settings → Branches, tambahkan aturan proteksi untuk branch main: wajibkan pull request dan centang status check test sebagai syarat. Dengan begitu kode yang membuat test gagal tidak bisa masuk ke main, termasuk oleh pemilik repository yang sedang terburu-buru.

Langkah 3: Simpan Kredensial Server di GitHub Secrets

Untuk deploy otomatis, GitHub perlu login ke server. Jangan pernah menulis password atau private key di file workflow. Buat pasangan kunci SSH khusus untuk deploy:

ssh-keygen -t ed25519 -C "github-deploy" -f ~/.ssh/github_deploy
# Salin isi github_deploy.pub ke ~/.ssh/authorized_keys di server

Lalu di Settings → Secrets and variables → Actions, tambahkan secret SSH_HOST, SSH_PORT, SSH_USER, dan SSH_KEY (isi file private key github_deploy). Prinsip yang sama dengan file .env berlaku di sini: secret tidak pernah ditulis di repository, dan kunci deploy ini hanya dipakai untuk satu keperluan sehingga mudah dicabut bila bocor.

Langkah 4: Tambahkan Job Deploy

Tambahkan job berikut di file yang sama, sejajar dengan job test:

  deploy:
    needs: test
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    runs-on: ubuntu-latest

    steps:
      - name: Deploy lewat SSH
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SSH_HOST }}
          port: ${{ secrets.SSH_PORT }}
          username: ${{ secrets.SSH_USER }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            set -e
            cd ~/apps/toko
            git pull origin main
            composer install --no-dev --optimize-autoloader --no-interaction
            php artisan migrate --force
            php artisan optimize

Dua baris kunci di job ini:

  • needs: test memastikan deploy hanya berjalan bila job test lulus.
  • if: memastikan deploy hanya terjadi pada push ke main, bukan pada pull request.

Perintah set -e di awal script menghentikan proses pada perintah pertama yang gagal, sehingga Anda tidak berakhir dengan kode baru yang berjalan tanpa migrasinya. Perintah php artisan optimize di akhir meng-cache konfigurasi dan route; langkah ini penting untuk performa, seperti dibahas di artikel caching di Laravel untuk performa.

Langkah 5: Pertimbangkan Mode Maintenance

Untuk perubahan yang menyentuh struktur database, Anda bisa mengapit proses dengan mode maintenance agar pengguna tidak melihat error di tengah deploy:

            php artisan down --retry=60
            # ... git pull, composer install, migrate, optimize ...
            php artisan up

Hati-hati: bila salah satu perintah di tengah gagal dan set -e aktif, aplikasi tetap dalam mode maintenance sampai Anda menjalankan php artisan up secara manual. Untuk deploy kecil yang tidak mengubah database, mode maintenance biasanya tidak diperlukan.

Masalah yang Sering Muncul

GejalaPenyebab umumSolusi
Test lulus di laptop, gagal di CITest bergantung pada data atau file lokal, atau versi PHP berbedaSamakan php-version, gunakan factory dan RefreshDatabase
Permission denied (publickey) saat deployPublic key belum ada di authorized_keys server, atau secret terpotongSalin ulang kunci lengkap termasuk baris BEGIN/END
git pull gagal karena perubahan lokalAda file yang diedit langsung di serverJangan mengedit kode di server; semua perubahan lewat Git
index.lock: File existsProses git sebelumnya terhenti di tengah jalanPastikan tidak ada proses git lain, hapus .git/index.lock, ulangi
Perubahan .env tidak terbacaKonfigurasi masih di-cacheJalankan php artisan optimize ulang setelah mengubah .env

Checklist Pipeline

  • Workflow CI berjalan di setiap push dan pull request.
  • Branch main diproteksi: merge hanya bila CI lulus.
  • Kredensial deploy tersimpan di GitHub Secrets dengan kunci SSH khusus.
  • Job deploy bergantung pada job test (needs: test).
  • Script deploy memakai set -e, menjalankan migrasi dengan --force, dan diakhiri php artisan optimize.
  • Tidak ada lagi perubahan kode yang dilakukan langsung di server.

Pipeline ini sengaja dibuat sederhana. Setelah berjalan stabil, Anda bisa menambahkan composer audit sebagai langkah CI, sebagai bagian dari best practice keamanan aplikasi web, sehingga paket yang rentan langsung ketahuan sebelum rilis.

Ingin langsung mempraktikkannya?

Buat akun gratis untuk mengunduh contoh aplikasi Laravel, menyimpan tutorial favorit, dan mencoba kursus. Gratis, bisa daftar dengan akun Google.

Daftar Gratis Lihat katalog aplikasi
Yudhi
Ditulis oleh
Yudhi
Founder & Lead Developer, GudangCode

Yudhi adalah founder GudangCode dan developer Laravel dengan pengalaman membangun puluhan sistem informasi bisnis siap pakai — mulai dari POS, HRIS, hingga aplikasi manajemen. Ia menulis panduan dan artikel di GudangCode untuk membantu developer Indonesia menjalankan, memahami, dan men-deploy source code Laravel dengan benar.

Laravel PHP MySQL Sistem Informasi Bisnis
Lihat semua artikel Yudhi
Ci Cd Github Actions Teknologi & Development
Bacaan Paling Dicari
📚 Free Learning Hub

Learn Coding for Free at DhieCoderWeb

Explore Laravel, PHP, JavaScript tutorials, source code, web development guides, and practical programming tips.

DhieCoderWeb
100+
Tutorials
Free
Learning
SEO
Tips
Visit Dhiecoderweb.com →