Pada proyek CodeIgniter 4, tim bisa langsung menyusun pipeline yang memaksa linting PHPStan dan PHP-CS-Fixer sebelum test, build, dan rilis otomatis. GitHub Actions menyediakan mekanisme untuk mengeksekusi urutan lint → test → build → publish dengan caching dependensi agar developer experience tetap cepat dan konsisten.

Panduan ini menunjukkan cara mengonfigurasi workflow lengkap, mengelola secret release, notifikasi, serta cara memantau dan memperbaiki kegagalan linting agar tidak ada perbaikan merusak rilis terbaru.

1. Komponen linting dan testing yang wajib

Di repositori CodeIgniter 4, pastikan ada konfigurasi PHPStan (phpstan.neon) dan aturan PHP-CS-Fixer (.php_cs.dist atau .php-cs-fixer.php). Kedua alat ini bekerja di fase linting: PHPStan memeriksa tipe dan struktur kode, sementara PHP-CS-Fixer menjaga gaya PSR yang ditentukan.

Tambahkan skrip composer agar konsisten dipanggil dari workflow:

"scripts": {
  "lint:phpstan": "phpstan analyse",
  "lint:php-cs-fixer": "php-cs-fixer fix --dry-run --diff"
}

Dengan begitu, GitHub Actions cukup memanggil composer lint:phpstan dan composer lint:php-cs-fixer tanpa mengulang konfigurasi.

2. Struktur workflow lint → test → build → publish

Berikut struktur minimal .github/workflows/ci-release.yml yang menegaskan urutan lint → test → build → publish:

name: CI & Release
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  workflow_dispatch:

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup PHP
        uses: shivammathur/setup-php@v3
        with:
          php-version: '8.2'
          extensions: mbstring, intl
      - name: Cache composer
        uses: actions/cache@v4
        with:
          path: ~/.composer/cache
          key: composer-${{ hashFiles('composer.lock') }}
      - name: Install dependencies
        run: composer install --no-progress --prefer-dist
      - name: PHPStan Lint
        run: composer lint:phpstan
      - name: PHP-CS-Fixer Lint
        run: composer lint:php-cs-fixer

  test:
    runs-on: ubuntu-latest
    needs: lint
    steps:
      - uses: actions/checkout@v4
      - name: Setup PHP
        uses: shivammathur/setup-php@v3
        with:
          php-version: '8.2'
      - name: Restore composer cache
        uses: actions/cache@v4
        with:
          path: ~/.composer/cache
          key: composer-${{ hashFiles('composer.lock') }}
      - name: Install dependencies
        run: composer install --no-progress --prefer-dist
      - name: Run Tests
        run: vendor/bin/phpunit

  build:
    runs-on: ubuntu-latest
    needs: test
    steps:
      - uses: actions/checkout@v4
      - name: Prepare build artifacts
        run: php spark build --env=production
      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: app-build
          path: build/

  release:
    runs-on: ubuntu-latest
    needs: build
    if: github.ref == 'refs/heads/main'
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
      - name: Download build
        uses: actions/download-artifact@v4
        with:
          name: app-build
          path: build/
      - name: Create GitHub Release
        uses: softprops/action-gh-release@v1
        with:
          tag_name: v${{ github.run_number }}
          name: Release ${{ github.run_number }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Urutan job memastikan lint harus berhasil sebelum test, lalu test sebelum build dan akhirnya release. Keuntungan pendekatan ini adalah kegagalan lint menghentikan pipeline paling awal, sehingga waktu build/test tidak terbuang.

3. Strategi caching dependensi

Untuk menjaga pipeline tetap responsif, gunakan actions/cache pada folder composer dan bisa diperluas ke cache PHPStan (~/.phpstan/cache) saat analisa intensif. Pastikan key menggabungkan composer.lock agar cache diperbarui saat dependensi berubah.

jika PHPStan menggunakan --memory-limit, cache lokal mempercepat iterasi ketika aturan berubah tapi kode tetap sama.

4. Mengamankan rilis otomatis

Pada job release, simpan informasi sensitif seperti token deploy di GitHub Secrets. Selain GITHUB_TOKEN bawaan, tambahkan:

  • RELEASE_SIGNING_KEY jika Anda menandatangani paket (misal, untuk artifact lain).
  • SLACK_WEBHOOK atau URL notifikasi jika ingin memberi tahu tim rilis telah selesai.

Gunakan Secrets hanya di job yang membutuhkannya dan atur permissions seminimal mungkin agar tidak memberi akses berlebih.

5. Mengelola kegagalan linting sebelum deploy

Linting gagal biasanya terjadi karena aturan PHPStan yang ketat atau PHP-CS-Fixer mendeteksi format tidak sesuai. Strategi perbaikan yang dianjurkan:

  1. Periksa output lint di GitHub Actions, fokus pada file dan baris yang disebut.
  2. Jalankan ulang linting lokal:
    composer lint:phpstan dan composer lint:php-cs-fixer.
  3. Untuk PHPStan, gunakan baseline untuk menangani code legacy:
    vendor/bin/phpstan analyse --generate-baseline kemudian commit file baseline, baru perbaiki pengingat nyata.
  4. Gunakan pre-commit atau pre-push hook (misal husky) agar developer mendapatkan feedback sebelum push.

Dengan menambahkan job lint sebelum job lain, tim bisa memperbaiki kesalahan dengan cepat sebelum pipeline lanjut, menjaga DX tetap cepat.

6. Notifikasi dan monitoring

Untuk memastikan tim tahu status rilis, tambahkan langkah notifikasi di akhir job release menggunakan action seperti 8398a7/action-slack@v4 atau Ilshidur/action-slack. Atur agar hanya mengirim saat success() atau failure() untuk memberikan konteks.

Selain itu, aktifkan proteksi branch main sehingga setiap pull request harus melewati workflow ini. GitHub juga menyediakan badge status dan history run yang bisa dipantau untuk debugging.

Penutup

Dengan menggabungkan linting PHPStan dan PHP-CS-Fixer, testing, build, serta release otomatis ke dalam satu workflow GitHub Actions, tim CodeIgniter 4 mendapatkan pipeline yang lebih solid dan developer experience yang responsif. Pastikan caching dependensi, pengelolaan secret, serta monitoring kegagalan lint menjadi bagian rutin. Ketika lint selalu menjadi pintu gerbang, tim bisa menjaga kualitas sebelum kode mencapai produksi.