jn-devops/common
jn-devops/common provides reusable Laravel/PHP utilities, service providers, configuration defaults, and shared helpers for consistent setup across jn-devops projects. It reduces boilerplate and keeps applications aligned with common DevOps conventions.
Because jn-devops/common has no public package registry presence (0 stars, 0 dependents), assume it's an internal package consumed via a VCS repository rather than Packagist. Start by confirming how it's meant to be installed before writing any code against it.
Register the source in the consumer app's composer.json if it isn't already resolvable:
"repositories": [
{ "type": "vcs", "url": "https://github.com/jn-devops/common" }
]
For private access, configure a GitHub token in auth.json or your CI secrets so composer install can clone it.
Install and inspect:
composer require jn-devops/common
Then read, in order:
composer.json — namespace under autoload.psr-4, Laravel version constraints, and whether a service provider is declared in extra.laravel.providers.src/ — the actual entry points (ServiceProvider, Facades, Traits, Models, Enums, Support helpers).config/ — if present, what's publishable.database/migrations/ — whether the package ships schema you're expected to run.Publish what's publishable (only if those tags exist):
php artisan vendor:publish --provider="JnDevops\Common\CommonServiceProvider"
First use case: pick the smallest surface area — typically a shared trait (e.g. a HasHomefulId or addressable/identifiable concern) on one existing Eloquent model, or a support helper — and wire it into a single feature branch. Don't adopt a base model or run package migrations across the whole app on day one; validate the package's assumptions against one model/table first.
If the README doesn't document the provider or namespace, run composer dump-autoload -o and use php artisan about / php artisan package:discover output to see what actually registered.
Trait composition on existing models. The most common pattern for a "common" package in a Laravel suite is shipping traits that add IDs, slugs, status enums, or address/contact behavior. Consume them narrowly:
use JnDevops\Common\Concerns\HasHomefulIdentifier;
class Property extends Model
{
use HasHomefulIdentifier;
}
Verify what the trait expects (columns, boot hooks, casts) by reading the trait source — traits that register static::creating() callbacks silently assume column names.
Shared contracts + config-driven bindings. If the provider binds interfaces (repositories, formatters, ID generators), prefer resolving through the container over new:
public function __construct(private ReferenceGenerator $refs) {}
Then override the binding in AppServiceProvider rather than editing vendor code when you need app-specific behavior.
Enums and DTOs across the Homeful suite. Where the package ships enums (status, type), use them in cast definitions and validation rules instead of duplicating string constants:
protected $casts = ['status' => PropertyStatus::class];
This is where a common package earns its keep — one source of truth for domain vocabulary across multiple apps.
Migrations and seeders. If the package ships migrations, treat them as part of your schema lineage: run them in order with your app migrations, and check timestamps so they don't collide with existing app migrations. For shared lookup tables, seed via the package's seeder in DatabaseSeeder rather than hand-rolling inserts.
Config publishing workflow. Publish config once, commit it, and treat the published file as yours. Use env() in the published file and re-publish only when the package adds new keys (diff the vendor config against yours before overwriting).
Testing pattern. In package-adjacent tests, use the real traits/bindings rather than mocks for value objects and enums, and RefreshDatabase for any package tables. If the package ships factories, alias them in TestCase setup.
"jn-devops/common": "1.2.*" or dev-main#abcdef) and upgrade deliberately. A dev-main constraint in a shared codebase will eventually break every app at once.composer dump-autoload and clear bootstrap/cache/*.php. "Class not found" after an update is almost always a stale autoload or cached manifest.php artisan config:cache will freeze published config; any env() calls outside the config file will return null in production. Keep env lookups in config/common.php and reference config('common.*') everywhere else.boot{TraitName}() hooks and scope methods with generic names (scopeActive, scopeForUser). If your model already has one, PHP will error at class load. Grep the trait before applying it broadly.bootstrap/providers.php (Laravel 11+) or config/app.php explicitly rather than relying on discovery.composer show jn-devops/common (confirm version and path), php artisan package:discover -v, then check storage/logs/laravel.log for provider boot failures. If it's installed from a VCS repo, confirm vendor/jn-devops/common is a real directory and not a symlink to a path you've since deleted.patches entry (via cweagans/composer-patches) if you hit a blocking bug.How can I help you explore Laravel packages today?