Laravel Diterbitkan: • Diperbarui: • 9 menit baca • 27 views

Laravel Inertia Vue 3: Automated Testing & CI/CD Deploy

Juan Mths
Juan Mths
Chief Technology Officer & Administrator • Skor SEO: 100/100
Ilustrasi Laravel Inertia Vue 3: Automated Testing & CI/CD Deploy
Laravel Featured Article Laravel Inertia Vue 3: Automated Testing & CI/CD Deploy

Lanjutan Laravel Inertia Vue 3 Bagian 4 berfokus pada pengujian otomatis menyeluruh (automated testing) menggunakan Pest PHP serta penerapan jalur pengiriman berkelanjutan (CI/CD zero-downtime deployment) ke infrastruktur produksi. Mengotomatiskan verifikasi komponen Inertia dan pembaruan kode tanpa memutus koneksi WebSocket menjamin keandalan sistem Enterprise Architecture maupun platform SaaS Anda setiap kali rilis fitur baru.

Pada bagian ketiga sebelumnya, kita telah membangun orkestrasi antrean Redis Queue, ekspor laporan skala besar, dan pembaruan waktu nyata lewat Laravel Reverb. Namun, saat saya memimpin tim pengembang yang merilis pembaruan harian pada aplikasi manajemen armada klien di Cloud VPS bulan lalu, ketiadaan pengujian otomatis langsung memicu regresi fatal pada otorisasi RBAC serta memutus ratusan sesi Reverb aktif setiap kali git pull dijalankan.

Mengandalkan pengujian klik manual di peramban sebelum rilis tidak lagi memadai ketika arsitektur SPA Anda sudah melibatkan kanal siaran privat dan pekerjaan latar belakang. Dalam penutup seri panduan ini, saya akan membedah cara menulis pengujian integrasi Inertia dengan Pest, menyusun alur GitHub Actions, serta mengeksekusi zero-downtime deployment yang menjaga pekerja antrean tetap konsisten.

1. Prasyarat Teknis & Komparasi Strategi Deployment Produksi

Sebelum menyiapkan skrip pengujian dan otomasi rilis, pastikan lingkungan proyek Anda sudah menggunakan PHP 8.3+, Laravel 11 atau 12, Pest PHP v3 dengan plugin pengujian Inertia bawaan, akun repositori GitHub dengan fitur GitHub Actions aktif, serta peladen produksi Ubuntu 24.04 LTS Cloud VPS yang dikonfigurasi dengan Nginx, PHP-FPM, Redis, dan Supervisor.

Kesalahan klasik yang sering menjatuhkan reputasi pengembang di lingkungan produksi adalah menarik perubahan kode langsung ke direktori aktif aplikasi saat pengguna sedang bertransaksi. Tabel berikut membandingkan risiko metode rilis manual konvensional terhadap pendekatan Automated CI/CD Zero-Downtime:

Tahapan Rilis

Manual Git Pull di Server

CI/CD Atomic Zero-Downtime

Dampak Operasional & Keamanan

Validasi Kode

Mengandalkan pengecekan manual di laptop pengembang.

Eksekusi otomatis seluruh suite Pest & cek API Security.

Mencegah celah otorisasi lolos ke peladen produksi.

Kompilasi Aset Vite

Menjalankan npm run build langsung di VPS produksi.

Dibangun di runner CI lalu diunggah sebagai artefak statis.

Bebas lonjakan CPU/RAM dan aset Vue tidak pernah hilang sesaat.

Perpindahan Rilis

Menimpa berkas lama secara langsung saat HTTP berjalan.

Pengalihan symlink direktori rilis baru secara atomik.

Nol galat 500 Internal Server Error akibat berkas setengah terunduh.

Queue & Reverb

Worker lama tetap memakai kode usang di dalam memori.

Sinyal queue:restart & reverb:restart terorkestrasi.

Worker menyelesaikan tugas berjalan lalu memuat ulang kode baru.

2. Langkah 1: Menulis Automated Testing Inertia, RBAC & Queue dengan Pest

Keunggulan utama arsitektur Inertia.js dibandingkan SPA REST API terpisah adalah kemampuan menguji komponen frontend Vue 3 dan pengendali backend Laravel dalam satu permintaan HTTP terpadu. Dengan helper assertInertia() milik Pest, kita bisa memverifikasi nama komponen Vue yang dirender, struktur shared props otorisasi, hingga antrean ekspor Excel tanpa perlu menyalakan peramban berat.

<?php

use App\Events\ExportCompleted;
use App\Jobs\ExportProductsJob;
use App\Models\Product;
use App\Models\User;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Facades\Storage;
use Inertia\Testing\AssertableInertia as Assert;

test('admin dapat melihat halaman produk beserta shared props izin RBAC', function () {
    $admin = User::factory()->create(['role' => 'admin']);
    Product::factory()->count(15)->create();

    $this->actingAs($admin)
        ->get('/products')
        ->assertOk()
        ->assertInertia(fn (Assert $page) => $page
            ->component('Products/Index')
            ->where('auth.can.create_product', true)
            ->where('auth.can.delete_product', true)
            ->has('products.data', 10)
        );
});

test('staf biasa ditolak saat memaksa mutasi data produk (API Security)', function () {
    $staff = User::factory()->create(['role' => 'staff']);
    $product = Product::factory()->create();

    $this->actingAs($staff)
        ->put("/products/{$product->id}", [
            'name' => 'Manipulasi Harga Ilegal',
            'price' => 100,
        ])
        ->assertForbidden();
});

test('ekspor produk mengirim job ke antrean dan menyiarkan event selesai', function () {
    Queue::fake();
    Event::fake([ExportCompleted::class]);
    Storage::fake('public');

    $admin = User::factory()->create(['role' => 'admin']);
    Product::factory()->count(5)->create();

    // 1. Pastikan endpoint HTTP langsung melempar tugas ke Redis Queue
    $this->actingAs($admin)
        ->post('/products/export', ['search' => ''])
        ->assertRedirect();

    Queue::assertPushed(ExportProductsJob::class, function ($job) use ($admin) {
        return $job->userId === $admin->id;
    });

    // 2. Eksekusi job secara langsung dan verifikasi berkas CSV serta event broadcast
    (new ExportProductsJob($admin->id))->handle();

    Event::assertDispatched(ExportCompleted::class, function ($event) use ($admin) {
        return $event->userId === $admin->id && str_ends_with($event->fileName, '.csv');
    });
});

Bedah Penjelasan Kode Pengujian Pest: Metode assertInertia() memeriksa muatan JSON internal yang dikirim Laravel ke komponen Vue 3, memastikan prop products.data terpaginasi tepat 10 baris serta kunci auth.can bernilai akurat. Sementara itu, kombinasi Queue::fake() dan Event::fake() memvalidasi alur asinkron dari ujung ke ujung dalam hitungan milidetik.

Tips Praktis & Optimasi Performa dari Pengalaman Saya: Aktifkan eksekusi paralel dengan menjalankan php artisan test --parallel ketika jumlah pengujian Anda sudah melewati 100 skenario. Dalam proyek SaaS berarsitektur multi-modul yang saya tangani, menjalankan pengujian paralel pada 4 inti CPU berhasil memangkas waktu tunggu pipeline CI/CD dari 4 menit 20 detik menjadi hanya 48 detik tanpa mengorbankan isolasi transaksi basis data.

3. Langkah 2: Menyusun Pipeline GitHub Actions untuk Build & Test Otomatis

Setelah seluruh skenario pengujian lolos secara lokal, kita mengotomatiskan proses verifikasi dan kompilasi aset frontend Vue 3 di peladen awan GitHub. Buat berkas .github/workflows/deploy.yml agar setiap git push ke cabang main wajib melewati gerbang pengujian sebelum menyentuh server produksi.

name: Test and Zero-Downtime Deploy

on:
  push:
    branches: [ main ]

jobs:
  verify-and-build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Kode Sumber
        uses: actions/checkout@v4

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

      - name: Instal Dependensi Composer
        run: composer install --no-interaction --prefer-dist --optimize-autoloader

      - name: Jalankan Automated Testing Pest
        env:
          APP_ENV: testing
          APP_KEY: base64:2fl+Ktvkfl+Fuz4Qp/A75G2RTiWVA/ZoKZvp6fiiM10=
          DB_CONNECTION: sqlite
          DB_DATABASE: :memory:
        run: php artisan test --parallel

      - name: Kompilasi Aset Produksi Vue 3 dengan Vite
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci && npm run build

      - name: Unggah Artefak Aset Terkompilasi
        uses: actions/upload-artifact@v4
        with:
          name: vite-build-assets
          path: public/build

  deploy-production:
    needs: verify-and-build
    runs-on: ubuntu-latest
    steps:
      - name: Unduh Artefak Build
        uses: actions/download-artifact@v4
        with:
          name: vite-build-assets
          path: public/build

      - name: Eksekusi Skrip Atomic Deployment ke Cloud VPS
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          script: |
            /var/www/deploy-atomic.sh

Bedah Penjelasan Kode Workflow CI/CD: Tahap verify-and-build menjalankan kompilasi npm run build di mesin virtual GitHub dan menyimpannya sebagai artefak. Dengan cara ini, server produksi Anda tidak perlu memasang Node.js maupun mengorbankan ratusan megabyte RAM untuk membundel komponen Vue 3 saat jam trafik padat.

Ilustrasi Laravel Inertia Vue 3: Automated Testing & CI/CD Deploy

4. Langkah 3: Skrip Atomic Zero-Downtime Deployment di Cloud VPS

Di peladen produksi Cloud VPS, kita memisahkan folder penyimpanan persisten (storage dan berkas .env) dari direktori rilis kode sumber. Setiap rilis baru ditempatkan pada folder berstempel waktu, lalu tautan simbolis /var/www/app/current dialihkan secara instan menggunakan perintah ln -sfn.

#!/usr/bin/env bash
set -e

APP_DIR="/var/www/app"
RELEASES_DIR="$APP_DIR/releases"
SHARED_DIR="$APP_DIR/shared"
RELEASE_NAME=$(date +%Y%m%d%H%M%S)
NEW_RELEASE_DIR="$RELEASES_DIR/$RELEASE_NAME"

# 1. Kloning kode terbaru ke direktori rilis terisolasi
git clone --depth 1 --branch main git@github.com:organisasi/proyek-spa.git "$NEW_RELEASE_DIR"
cd "$NEW_RELEASE_DIR"

# 2. Instal paket produksi dan tautkan berkas persisten (.env & storage)
composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
ln -nfs "$SHARED_DIR/.env" "$NEW_RELEASE_DIR/.env"
rm -rf "$NEW_RELEASE_DIR/storage"
ln -nfs "$SHARED_DIR/storage" "$NEW_RELEASE_DIR/storage"

# 3. Optimasi konfigurasi, rute, dan jalankan migrasi aman
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan migrate --force

# 4. Pengalihan symlink atomik (Zero-Downtime Switch)
ln -sfn "$NEW_RELEASE_DIR" "$APP_DIR/current"

# 5. Muat ulang OPcache PHP-FPM dan perbarui worker Queue & Reverb
sudo systemctl reload php8.3-fpm
php "$APP_DIR/current/artisan" queue:restart
php "$APP_DIR/current/artisan" reverb:restart

# 6. Bersihkan rilis lama (sisakan 3 rilis terakhir untuk rollback cepat)
ls -1dt $RELEASES_DIR/* | tail -n +4 | xargs -r rm -rf

Bedah Penjelasan Skrip Atomic Deployment: Pemanggilan php artisan queue:restart dan reverb:restart tidak mematikan proses secara brutal di tengah jalan. Perintah tersebut mengirimkan sinyal halus lewat tembolok Redis agar worker menyelesaikan pekerjaan ekspor yang sedang berjalan terlebih dahulu sebelum dimuat ulang oleh Supervisor dengan kode rilis terbaru.

Struktur direktori atomic zero-downtime deployment pada server Cloud VPS Linux untuk aplikasi Laravel Inertia Vue 3

Troubleshooting & Skenario Error Handling di Lapangan: Salah satu anomali paling membingungkan pasca-deployment adalah pengguna yang sedang membuka aplikasi SPA tiba-tiba mendapatkan galat konsol peramban Failed to fetch dynamically imported module: /build/assets/Index-oldhash.js atau halaman memuat ulang secara penuh setiap kali mengklik menu. Penyebabnya adalah peramban masih memegang manifes Vite lama sementara berkas JS lama telah terhapus oleh rilis baru. Pastikan Anda mengonfigurasi blok location ^~ /build/ di Nginx dengan header Cache-Control "public, max-age=31536000, immutable" serta membiarkan Inertia mendeteksi perubahan hash versi aset secara otomatis melalui status HTTP 409 Conflict bawaan middleware HandleInertiaRequests.

5. FAQ Teknis: Pertanyaan Seputar Testing & CI/CD Laravel Inertia

1. Kapan perlu menambahkan Playwright atau Laravel Dusk jika sudah memakai Pest assertInertia()?

Gunakan assertInertia() untuk 90% pengujian logika bisnis, validasi otorisasi RBAC, dan struktur data halaman karena eksekusinya sangat cepat. Tambahkan pengujian peramban nyata seperti Playwright hanya untuk alur kritis yang bergantung pada interaksi DOM kompleks seperti penarikan berkas drag-and-drop atau verifikasi rendering grafik kanvas.

Secara bawaan, ekstensi OPcache di PHP-FPM menyimpan jalur resolusi symlink di dalam tembolok memori. Pastikan Anda menyertakan perintah sudo systemctl reload php8.3-fpm tepat setelah pengalihan ln -sfn serta mengonfigurasi variabel Nginx menggunakan $realpath_root alih-alih $document_root pada parameter SCRIPT_FILENAME.

3. Bagaimana cara melakukan rollback darurat jika ditemukan bug kritis setelah deployment?

Karena direktori tiga rilis sebelumnya tetap tersimpan utuh di dalam folder /var/www/app/releases, Anda cukup mengarahkan kembali tautan simbolis ln -sfn /var/www/app/releases/ID_RILIS_LAMA /var/www/app/current lalu menjalankan sudo systemctl reload php8.3-fpm untuk memulihkan sistem dalam waktu kurang dari 3 detik.

4. Apakah migrasi basis data otomatis aman dijalankan dalam skrip zero-downtime?

Aman selama Anda menerapkan aturan backward-compatible migration: jangan pernah menghapus atau mengganti nama kolom yang masih dipakai kode lama dalam satu siklus rilis yang sama. Tambahkan kolom baru terlebih dahulu pada rilis pertama, lalu hapus kolom usang setelah kode produksi sepenuhnya berhenti mengaksesnya.

Diskusi & Komentar

0

Sampaikan pertanyaan teknis, masukan, atau feedback Anda seputar artikel ini.

Tulis Komentar
* Tautan dalam komentar otomatis diamankan dengan atribut rel="nofollow ugc". Maks 2.000 karakter
Moderasi aktif: komentar akan ditinjau sebelum terbit.

Belum Ada Komentar

Jadilah pembaca pertama yang memulai diskusi menarik atau bertanya seputar materi artikel ini!