jeffersongoncalves/filament-satis
A Filament plugin for managing Satis, the static Composer repository generator. Configure private package repositories, define sources, and build Satis outputs directly from your Filament admin panel, simplifying private Composer hosting for Laravel and PHP projects.
jeffersongoncalves/filament-satis is a Filament panel plugin that surfaces your Satis private Composer repository inside the admin UI — browsing the package index, inspecting versions, and triggering/refreshing builds without SSH-ing into the build box.
Minimal setup:
composer require jeffersongoncalves/filament-satis
php artisan vendor:publish --tag="filament-satis-config" # config + migrations if present
php artisan migrate
Register the plugin on the panel you want it on (typically an internal/admin panel, not a customer-facing one):
use JeffersonGoncalves\FilamentSatis\FilamentSatisPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugin(FilamentSatisPlugin::make());
}
Look first at the published config/filament-satis.php — that's where the Satis output directory / satis.json path and any auth-gate/authorization callbacks live. Verify those paths resolve inside the container before touching anything else; a wrong path is the #1 reason the resource renders empty.
First use case: point the plugin at an existing satis.json + output dir, open the packages resource, and confirm the list matches satis.json's require block. That validates config before you wire up build triggering.
New in 1.13.0: the UI ships 17 locales (ar, az, de, es, fa, fr, hi, it, ja, nl, pl, pt, ru, tr, uk, uz, zh_CN). No config needed — Filament picks them up via the panel locale. If your admin panel runs ->locale('de') or users switch language per-user, labels/buttons now translate automatically.
Gate the plugin behind a policy or role. Satis metadata reveals private package names and versions. Don't rely on panel access alone:
FilamentSatisPlugin::make()
->authorize(fn () => auth()->user()?->hasRole('release-manager'));
(or use Filament's canAccessPanel / a dedicated Policy — whichever the plugin exposes; check the plugin class for the fluent authorize()/visible() methods on this version before assuming).
Pair the resource with a scheduled Satis rebuild. The plugin is a viewer/trigger; the actual satis build should stay in a queued job or scheduler so builds aren't coupled to a web request:
Schedule::command('satis:build')->hourly();
Then use the plugin's trigger action purely as an on-demand "rebuild now" for release managers, pointing it at a job rather than shelling out inline.
Multi-panel / multi-repo layouts. If you host more than one Satis repo (e.g. per team), register the plugin only on the relevant panel and switch the config via ->configPath(...)-style scoping, or publish one config per environment. Keeping one repo per panel avoids ambiguous UI.
Localization for distributed teams. With 1.13.0, set ->locale() per panel or let users pick their language; the new translations cover most of EMEA, CIS, and CJK. Add zh_CN/ar/fa to your config/app.php locales list so the switcher exposes them.
Combine with Composer auth. Your Satis repo is usually protected by HTTP basic or a token. If the plugin needs to read remote metadata, ensure the credentials are in the panel's .env and referenced from the config, not hardcoded — the plugin will use them when fetching.
packages.json/include files, not satis.json directly. If satis build hasn't run or wrote to a different directory, the resource is blank with no obvious error. Verify path + file permissions of the web user.satis build synchronously — it clones every dependency. Queue it and poll/refresh. Watch for PHP max_execution_time and memory if the plugin ships a sync fallback.php artisan filament:optimize-clear (or the plugin's refresh action) so the UI reflects new versions.->label() or your own pages won't be translated — keep those in your app's lang/ files rather than editing the package's.lang/vendor/filament-satis, re-check for key changes.--tag="filament-satis-views") rather than forking, which keeps the translation updates coming in cleanly.storage/logs/laravel.log + failed_jobs table).canAccessPanel guard so customer auth can never reach it.How can I help you explore Laravel packages today?