Pada proyek Laravel yang kompleks, menjalankan lint dan berbagai suite test secara berurutan membuat waktu build membengkak. Solusi praktisnya adalah Pipeline Matrix Paralel di GitHub Actions: setiap kombinasi linting dan testing dijalankan dalam job terpisah berdasarkan konfigurasi matriks, sehingga linting PHPStan/Pint dan test unit/integration/e2e berjalan bersamaan dan memanfaatkan sumber daya runner secara optimal.

Artikel ini langsung menunjukkan bagaimana menyusun workflow tersebut, termasuk cache vendor untuk Composer, mekanisme retry untuk job flake, serta pelaporan hasil agar tim dapat mengetahui status linting dan test dengan cepat.

Menetapkan Pipeline Matrix Paralel

Github Actions memungkinkan kita membuat satu job dengan matrix yang berbeda untuk setiap kombinasi lint dan test. Untuk Laravel, bentuk matriks sederhana bisa mencakup entry yang membawa nama tugas dan perintah untuk dijalankan:

jobs:
  pipeline-matrix:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        task:
          - name: phpstan
            command: vendor/bin/phpstan analyse
          - name: pint
            command: vendor/bin/pint --test
          - name: unit
            command: php artisan test --parallel --testsuite=Unit
          - name: integration
            command: php artisan test --parallel --testsuite=Integration
          - name: e2e
            command: vendor/bin/phpunit --testsuite=E2E
      fail-fast: false
    steps:
      ...

Setiap entry matrix mengeksekusi command yang relevan. Dengan fail-fast: false kita menghindari penghentian seluruh matriks saat satu job gagal, memungkinkan linting lain tetap berjalan untuk laporan yang komprehensif.

Detail Workflow GitHub Actions

Berikut struktur langkah penting yang secara bertahap dilakukan di setiap job:

  • Checkout kode menggunakan actions/checkout@v4.
  • Setup PHP dan ekstensi sesuai composer.lock agar versi konsisten.
  • Cache vendor dengan actions/cache untuk mempercepat composer install.
  • Jalankan perintah lint/test dari entry matrix.
  • Upload artefak (log atau file junit) untuk reporting.

Bagian linting menggunakan PHPStan dan Pint, yang menyediakan static analysis dan gaya kode. Untuk testing Laravel, pisahkan suite (Unit, Integration, E2E) agar bisa diberi konteks berbeda terkait database, queue, atau browser environment.

Contoh Workflow Lengkap

name: Laravel CI

on:
  pull_request:
    branches: [main]

jobs:
  pipeline-matrix:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        task:
          - name: phpstan
            command: vendor/bin/phpstan analyse
          - name: pint
            command: vendor/bin/pint --test
          - name: unit
            command: php artisan test --parallel --testsuite=Unit
          - name: integration
            command: php artisan test --parallel --testsuite=Integration
          - name: e2e
            command: vendor/bin/phpunit --testsuite=E2E --log-junit=artifacts/%MATRIX_TASK%.xml
      fail-fast: false
      max-parallel: 3
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v3
        with:
          php-version: '8.2'
          extensions: mbstring, pdo_mysql

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

      - name: Install dependencies
        run: composer install --no-progress --prefer-dist

      - name: Jalankan ${{ matrix.task.name }}
        run: ./${{ matrix.task.command }}

Kunci matriks adalah memisahkan setiap tugas agar bisa diparalelkan, sementara max-parallel menahan jumlah job sekaligus agar tidak overburden runner. Jika pipeline Anda memiliki resource lebih, angka ini bisa dinaikkan.

Mekanisme Retry untuk Job Flake

Flake test bisa disebabkan race condition, koneksi eksternal, atau queue worker startup. Karena GitHub Actions tidak menyediakan retry otomatis per job, kita bisa bungkus perintah yang rawan dengan skrip retry sederhana:

- name: Jalankan ${{ matrix.task.name }} dengan retry
  run: |
    retries=0
    until [ $retries -ge 2 ]; do
      {{ matrix.task.command }} && break
      retries=$((retries + 1))
      echo "Percobaan ulang ke-$retries"
      sleep 10
    done
    if [ $retries -ge 2 ]; then
      exit 1
    fi

Implementasi di atas mencoba ulang hingga dua kali sebelum menandai job gagal. Pastikan perintah yang diberi retry idempoten dan tidak menulis state penting di luar lingkungan build.

Cache dan Pelaporan Hasil

Cache vendor menghemat waktu install composer, yang paling lama pada pipeline PHP. Selain itu, unggah log linting dan test agar failure bisa dianalisis:

- name: Upload log linting
  if: failure()
  uses: actions/upload-artifact@v4
  with:
    name: lint-log-${{ matrix.task.name }}
    path: storage/logs/lint-${{ matrix.task.name }}.log

Untuk test suites, jalankan perintah dengan opsi log junit dan upload file tersebut:

- name: Upload laporan test
  if: always()
  uses: actions/upload-artifact@v4
  with:
    name: test-report-${{ matrix.task.name }}
    path: artifacts/${{ matrix.task.name }}.xml

Hasil ini bisa diunduh dari tab Actions atau dipaketkan dengan dashboard CI untuk analisis tren.

Tips Menjaga Waktu Build Konsisten Saat Menambah Job

  • Monitor waktu job terbaru dan bandingkan dengan baseline pipeline. Jika suatu job memakan waktu lebih dari rata-rata, evaluasi apakah sudah perlu dijalankan setiap PR atau bisa diturunkan ke schedule tertentu.
  • Gunakan cache yang tepat dan pastikan composer install hanya dijalankan bila ada perubahan pada composer.lock. Tambahkan cache terpisah untuk node_modules jika ada front-end.
  • Evaluasi paralelisme secara berkala. Pipeline yang terlalu paralel dapat membuat queue dan database test saling tabrakan; sesuaikan max-parallel atau group job berdasarkan dependency lingkungan.
  • Tambah alert atau dashboard untuk job yang sering retry agar bisa diinvestigasi. Retry membantu stabilitas, tapi jika selalu terpicu berarti ada flake yang perlu diperbaiki.

Strategi matriks yang diasah secara terus-menerus menjaga linting dan testing Laravel tetap cepat tanpa mengorbankan kualitas. Dengan caching, retry, dan reporting yang tertata, pipeline akan tetap dapat diskalakan saat kebutuhan bertambah.