Rollback
Melakukan rollback pada application yang menggunakan PandaBear berarti mengembalikan lebih dari sekadar PHP code. Ada lima area yang harus dipikirkan bersama:
- PHP/code release;
- cache;
- database schema;
- published frontend + built bundle;
- queue/long-lived process.
Empat di antaranya adalah problem Laravel umum. Yang kelima — Panel manifest — memiliki failure mode khusus yang penting diketahui sebelum insiden terjadi, karena dapat membuat Resource/Page hilang tanpa log apa pun.
Gunakan halaman ini saat menulis rollback script atau ketika rollback sedang dilakukan.
Contoh minimal yang berfungsi
Rollback ke release directory sebelumnya:
ln -sfn /var/www/releases/41 /var/www/current
cd /var/www/releases/41
php artisan optimize:clear # config, routes, views, events — dan panel:clear
php artisan optimize # rebuild semuanya dari release ini
php artisan queue:restart
php artisan octane:reload # jika Octane berjalan2
3
4
5
6
7
Bagian paling penting adalah clear lalu rebuild. Mengubah symlink saja dapat meninggalkan cache dari release yang lebih baru.
Apa saja yang harus ikut dikembalikan
| Bagian | Dikembalikan dengan | Jika dilewati |
|---|---|---|
| PHP code | symlink atau git checkout | — |
| Config/route/view/event cache | optimize:clear lalu optimize | application dapat tetap memakai config/route dari release yang baru saja di-rollback |
| Panel manifest | pasangan command yang sama | Panel dapat menyebut class yang sudah tidak ada atau kehilangan class yang seharusnya ada |
| Published Vue components | ikut code repository | component release baru dapat memanggil backend API yang sudah tidak ada |
| Built frontend bundle | npm ci && npm run build pada release lama | bundle release baru tetap dilayani |
| Schema | php artisan migrate:rollback jika aman | biasanya lebih aman dibiarkan maju; lihat bagian migration |
| In-flight jobs | queue:restart, kadang queue:flush | job lama dapat menyebut class yang dihapus rollback |
Panel manifest
Ini adalah risiko PandaBear yang paling spesifik, dan penyebab utamanya satu:
bootstrap/cachedishare antar-release.
Manifest menyimpan class name berdasarkan code pada satu release:
return array (
'panels' => array (
'admin' => array (
'resources' => array (
0 => 'App\\Panels\\Admin\\Resources\\Users\\UserResource',
1 => 'App\\Panels\\Admin\\Resources\\Invoices\\InvoiceResource', // ditambahkan pada release 42
),
// …
),
),
'fingerprint' => '…',
);2
3
4
5
6
7
8
9
10
11
12
Jika rollback ke release 41 tetapi file manifest release 42 masih dipakai, Panel dapat mencoba mendaftarkan InvoiceResource yang sudah tidak ada.
Jika rollback dilakukan tanpa manifest, discovery akan berjalan lagi. Itu lebih lambat, tetapi benar.
php artisan panel:clear # selalu aman; manifest yang tidak ada dianggap success
php artisan panel:cache # rebuild dari code release yang benar-benar aktif2
Kedua command sudah terintegrasi dengan optimize:clear dan optimize, sehingga rollback script yang menjalankan kedua command Laravel tersebut tidak perlu baris tambahan khusus Panel.
Stale warning tidak tersedia di production
// PanelManifest::warnIfStale()
if (! app()->hasDebugModeEnabled() && ! app()->environment('local', 'testing')) {
return;
}2
3
4
Fingerprint warning yang dapat menemukan manifest stale hanya aktif di development/debug. Production rollback tidak mendapatkan warning tersebut.
Karena itu:
Bersihkan dan rebuild cache secara unconditional. Jangan mencoba menebak apakah manifest masih valid.
API yang relevan:
| Method | Signature | Kegunaan rollback |
|---|---|---|
clear | clear(): bool | menghapus manifest; true selama hasil akhirnya manifest tidak ada, termasuk jika sejak awal memang tidak ada |
exists | exists(): bool | memverifikasi hasil rebuild |
write | write(PanelRegistry $registry): array | method yang digunakan panel:cache |
use PandaPanel\Cache\PanelManifest;
app(PanelManifest::class)->clear();
app(PanelManifest::class)->exists(); // false2
3
4
Jadikan bootstrap/cache milik masing-masing release
| Directory | Shared antar-release? |
|---|---|
storage | ya |
.env | ya |
bootstrap/cache | tidak |
Membagikan bootstrap/cache dapat mengubah rollback sederhana menjadi incident. Jika cache per-release, release lama masih memiliki cache yang cocok dengan code-nya sendiri; rebuild menjadi safety tambahan, bukan satu-satunya hal yang mencegah failure.
Route cache
Route cache dibangun dari registry Panel yang pada akhirnya berasal dari manifest.
Rollback code tetapi membiarkan compiled route table baru dapat mempertahankan route untuk Resource/Page yang sudah tidak ada.
php artisan route:clear
php artisan route:cache
php artisan route:list --path=admin2
3
Dua mismatch umum:
| Kondisi setelah rollback | Gejala |
|---|---|
| Route cache baru, code lama | URL dapat mengarah ke controller/Page class yang sudah tidak ada |
| Route cache lama, manifest baru | sidebar menampilkan link yang 404 |
Keduanya dapat gagal tanpa log yang jelas.
Rollback package PandaBear
Contoh downgrade package:
composer require chocoalano/panel:0.1.6 --update-with-dependencies
php artisan optimize:clear
php artisan optimize2
3
Downgrade mengubah source frontend yang dikirim package, sehingga status panel:assets juga berubah:
php artisan panel:assetsContoh:
out of date 7
CONFLICT 1
yours 3
current 2862
3
4
Status yang count-nya nol tidak dicetak, sehingga bentuk summary dapat berbeda setiap run.
Pada downgrade, baca label out of date sebagai:
“berbeda dari versi package yang sekarang ter-install”
bukan selalu “lebih lama”.
Jadi --update setelah downgrade akan menulis copy yang lebih lama dari package terhadap file yang application tidak pernah modifikasi. Itu benar karena frontend source harus mengikuti versi PHP yang baru saja dikembalikan.
php artisan panel:assets --update
npm run build2
File yang diedit application tidak ditimpa. File yang berubah di kedua sisi dilaporkan sebagai conflict dan dibiarkan apa adanya.
Commit .panel-assets.json. File tersebut menyimpan hash setiap asset sebagaimana saat dipublish dan menjadi common ancestor untuk menentukan apakah application atau package yang berubah.
Migration
Migration package bersifat additive dan guarded.
| Migration | Saran saat rollback |
|---|---|
create_notifications_table | jangan rollback selama application masih menggunakan Panel notification; bell membacanya pada setiap Panel request |
add_email_two_factor_to_users_table | aman dibiarkan; unused nullable column tidak merusak code lama |
create_panel_integrations_table | aman dibiarkan |
add_history_and_signing_to_panel_integrations | aman dibiarkan |
Secara umum schema lebih maju daripada code jauh lebih aman dibanding schema tertinggal dari code.
SharePanelData memang menangkap QueryException saat unread notification count dan fallback ke 0, sehingga missing notifications table tidak langsung membuat 500. Tetapi itu safety net, bukan alasan menghapus table saat rollback.
Rollback migration application sendiri tetap merupakan keputusan application dan merupakan bagian yang berpotensi kehilangan data:
php artisan migrate:rollback --step=1 --forceQueue
Job dari release baru dapat masih berada di queue ketika rollback dilakukan.
Job PandaBear membawa class name sebagai string:
RunPanelExport::dispatch(
$exporter, // class-string<Exporter>
$resource, // class-string<Resource>
// …
);2
3
4
5
Jika rollback menghapus exporter/resource tersebut, worker akan gagal ketika mencoba me-resolve class.
Ini menghasilkan failed job, bukan corrupted job. Tetapi dari sisi user, mereka menunggu file/notifikasi yang tidak akan selesai.
php artisan queue:restart # selalu
php artisan queue:failed # lihat job yang tidak survive rollback
php artisan queue:flush # hanya jika seluruh failure memang berasal dari release yang dibatalkan2
3
Jika deployment window memungkinkan, mengosongkan/drain queue sebelum symlink rollback adalah kondisi paling bersih.
Frontend
Published source component berada di repository, sehingga code rollback ikut mengembalikannya.
Tetapi dua hal tidak otomatis kembali:
Built bundle
Build ulang dari release yang dikembalikan:
npm ci
npm run build2
Atau restore build artifact yang memang diproduksi bersama release tersebut.
Menjalankan bundle release 42 terhadap PHP release 41 sama buruknya dengan deploy maju tanpa rebuild.
VITE_*
Environment variable VITE_* di-inline saat build. Rollback yang juga mengembalikan environment variable harus rebuild agar bundle membaca value lama.
Icon registry adalah tracked source file dan ikut rollback code. Tidak perlu menjalankan panel:icons saat rollback; command tersebut justru akan menulis file baru yang tidak pernah dicommit.
Rollback perubahan Panel id
Mengganti Panel id mengubah beberapa hal sekaligus:
| Diturunkan dari Panel id | Contoh |
|---|---|
| Route name | panel.admin.dashboard |
| Manifest key | 'admin' => [...] |
| Generated Wayfinder module | ikut di-compile ke bundle |
Karena itu rename dan rollback rename harus diperlakukan sebagai:
clear seluruh cache
rebuild seluruh cache
regenerate frontend route modules
rebuild frontend2
3
4
Manifest entry dengan id yang tidak lagi dimiliki Panel tidak selalu fatal; Panel baru dapat fallback ke discovery. Tetapi route() yang masih menyebut id lama dapat menghasilkan RouteNotFoundException.
Contoh rollback script
#!/usr/bin/env bash
set -euo pipefail
PREVIOUS=/var/www/releases/41
php artisan down --render="errors::503"
ln -sfn "$PREVIOUS" /var/www/current
cd "$PREVIOUS"
php artisan optimize:clear
php artisan optimize
npm ci
npm run build
php artisan queue:restart
php artisan octane:reload || true
php artisan up2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
optimize:clear tetap dijalankan sebelum optimize, bukan hanya mengandalkan rebuild overwrite. panel:clear idempotent dan murah, sehingga pasangan clear→build menyatakan intent rollback dengan jelas.
Hal yang perlu diperhatikan
- Shared
bootstrap/cacheadalah masalah terbesar. Banyak failure rollback lain mudah terlihat; manifest mismatch bisa senyap. - Production tidak memiliki stale-manifest warning. Fingerprint check development tidak menolong rollback live.
panel:clearaman dijalankan dua kali dan aman pada machine yang belum pernah cache.panel:assetssetelah downgrade dapat menyebut file yang sebenarnya “terlalu baru” sebagaiout of date. Label berarti berbeda, bukan arah versi.- Jangan rollback
create_notifications_tableselama Notification Centre tetap digunakan. - In-flight job dapat hidup lebih lama dari release. Restart worker dan periksa
queue:failed. - Frontend bundle tidak berada dalam Panel manifest. Rebuild frontend tetap langkah terpisah.