misodrobny/application-versioning
Laravel package for application versioning that helps you manage and expose your app's version consistently. Configure version details, display them in views or API responses, and keep release information centralized across environments. Useful for release tracking, status pages, and support workflo...
composer require the versioning package, then publish its config: php artisan vendor:publish --tag=application-versioning-config (check the package's provider for the exact tag). This creates config/application-versioning.php.version.yaml at the path in version_file_path. If your app lives on a read-only filesystem (Vapor/Lambda, hardened containers, some Forge/Cloud setups), set the new disk options instead:
'disk' => env('APP_VERSIONING_DISK'), // e.g. 's3'
'disk_path' => env('APP_VERSIONING_DISK_PATH', 'version.yaml'),
When disk is null the local file is used exactly as before, so existing installs need no change.use ApplicationVersioning\Facades\ApplicationVersion; // verify exact FQCN in the package
Route::get('/health', fn () => response()->json([
'version' => ApplicationVersion::getFormatedVersion(),
]));
php artisan list them under the package namespace) to see how version.yaml is written before wiring it into a pipeline.getFormatedVersion(), the install command and the increase command all pull the singleton from the container. Follow suit in your own code — app(ApplicationVersioning::class) or the ApplicationVersion facade — rather than new ApplicationVersioning(...). This keeps a single source of truth for config and any cached read.?v={{ ApplicationVersion::getFormatedVersion() }}) so a deploy invalidates CDN/browser caches without a separate build number.version.yaml on S3, and every app instance picks it up.APP_VERSIONING_DISK with a disk whose credentials are available at runtime, and keep APP_VERSIONING_DISK_PATH stable across environments. Use distinct paths/buckets per environment (staging vs production) so commands don't bump the wrong version.getFormatedVersion() composes the config version with GitSupport::getCurrentHeadHash(). In 0.2.0 that hash now resolves correctly on a detached HEAD (deployments that check out a commit) and for refs living only in packed-refs (post-git gc, fresh clones). If .git is missing or unreadable at all, the hash defaults to empty rather than throwing — so you can call it unconditionally in health checks without a try/catch.ApplicationVersioning (or point version_file_path/disk at a fixture) in your test case so assertions on version strings don't depend on the repo's .git state.getFormatedVersion() is spelled with one t. It's the public API name; don't "fix" it in your code or you'll get a BadMethodCallException. Consider wrapping it in a small helper of your own (app_version()) to isolate the typo and make it swappable later.disk and disk_path keys. Existing published configs won't have them; add the two lines manually or re-publish. Note that re-publishing can overwrite local customisations — diff before you confirm.config:cache interaction. Env-driven values (APP_VERSIONING_DISK, APP_VERSIONING_DISK_PATH) are baked in at cache time. Changing them requires php artisan config:cache again, which is a common "why is it still writing locally?" cause.version_file_path (local) and disk_path (disk) are independent settings. Setting disk silently ignores version_file_path; keep both documented in your .env.example to avoid confusion between environments.version.yaml if you bump from a request; prefer bumping only from CLI/CI so the file isn't a writable web target. For disks, verify the disk's throw behaviour — a failed write from the increase command is easier to catch than an empty read at runtime.APP_VERSIONING_DISK actually set in the running process, disk_path contents, then the local file. When the git hash is empty in the output, confirm .git is present and readable in the deployed artifact — many build images strip it, and 0.2.0's new default-on-error means you'll get a version without a hash rather than an exception, which can mask the real cause.symfony/yaml is now ^7.1|^8.0 for Laravel 13 compatibility, and tests cover Laravel 11/12/13. Laravel 10 (Symfony 6) is effectively out of range, so pin accordingly if you're still on it. No breaking changes in this release, so the upgrade is a composer update plus the optional config keys.How can I help you explore Laravel packages today?