Looking to hire Laravel developers? Try LaraJobs

laravel-release-manager maintained by sunnynath

Description
Enterprise-grade release metadata and version governance package for Laravel applications
Author
SunnyNath
Last update
2026/05/17 18:57 (dev-master)
License
Links
Downloads
2

Comments
comments powered by Disqus

Laravel Release Manager

Enterprise-ready application release metadata and version governance for Laravel applications.

sunnynath/laravel-release-manager is a standalone Laravel package for exposing, resolving, caching, and automating application release metadata. It is designed for teams that need a reliable way to answer simple but important production questions:

  • What version is currently deployed?
  • Which build, branch, and commit produced this runtime?
  • Where should release metadata come from in CI/CD?
  • How can APIs and operational tooling expose release details safely?
  • How can Git tags and version files stay in sync?

The package follows Semantic Versioning for application release versions and supports Laravel package auto-discovery.

Requirements

  • PHP 8.2 or higher
  • Laravel 10, 11, or 12
  • Composer
  • Git, only when using Git-backed release automation commands

Installation

Install the package with Composer:

composer require sunnynath/laravel-release-manager

Laravel auto-discovers the service provider and facade. Publish the configuration file:

php artisan vendor:publish --tag=release-manager-config

This publishes:

config/release-manager.php

Quick Start

Set a release version in your environment:

RELEASE_VERSION=1.2.3
RELEASE_BUILD_NUMBER=20260517.1
RELEASE_COMMIT_HASH=abc1234
RELEASE_BRANCH=main

Show the current release metadata:

php artisan release:show

Use the helper functions anywhere in your Laravel app:

$version = release_version();
$metadata = release_metadata();

Render the application version in Blade:

@appVersion

Use the facade:

use Sunnynath\LaravelReleaseManager\Facades\Release;

$version = Release::version();
$metadata = Release::metadata();

Configuration

After publishing the config file, configure release metadata in config/release-manager.php.

Common environment variables:

RELEASE_VERSION=1.2.3
RELEASE_FALLBACK_VERSION=0.1.0
RELEASE_VERSION_FILE=/absolute/path/to/VERSION
RELEASE_BUILD_NUMBER=20260517.1
RELEASE_COMMIT_HASH=abc1234
RELEASE_BRANCH=main
RELEASE_CHANNEL=stable
RELEASE_CHANGELOG_URL=https://example.com/changelog
APP_ENV=production

Cache configuration:

RELEASE_CACHE_ENABLED=true
RELEASE_CACHE_TTL=300
RELEASE_CACHE_STORE=array

Optional metadata endpoint configuration:

RELEASE_METADATA_ENDPOINT_ENABLED=false
RELEASE_METADATA_ENDPOINT_PATH=release

Git automation configuration:

RELEASE_GIT_PATH=/path/to/application
RELEASE_GIT_BINARY=git
RELEASE_GIT_TIMEOUT=30
RELEASE_GIT_TAG_PATTERN=v*
RELEASE_GIT_TAG_PREFIX=v
RELEASE_GIT_INCLUDE_UNPREFIXED_TAGS=true

Compatibility governance configuration:

RELEASE_COMPATIBILITY_ENABLED=true
RELEASE_MIN_CLIENT_VERSION=2.0.0
RELEASE_CLIENT_VERSION_HEADER=X-Client-Version
RELEASE_ALLOW_MISSING_CLIENT_VERSION=false
RELEASE_INCOMPATIBLE_STATUS=426

Audit logging configuration:

RELEASE_AUDIT_ENABLED=true

Version Resolution

Versions are resolved from configured sources in deterministic priority order. The first source that returns a non-empty valid Semantic Version wins.

'sources' => [
    'priority' => [
        'env',
        'config',
        'file',
        'git',
    ],
],

Available sources:

Source Description
env Reads the configured environment key, usually RELEASE_VERSION.
config Reads a Laravel config key, usually release-manager.version.
file Reads a version string from a configured file.
git Reads the latest valid Semantic Version from Git tags.

If no configured source returns a version, the package uses fallback_version.

Supported version examples:

1.2.3
v1.2.3
1.2.3-beta.1
1.2.3+build.42
1.2.3-rc.1+build.42

The leading v is accepted and normalized away.

Release Metadata

release_metadata() and Release::metadata() return a ReleaseMetadata value object with:

Field Description
version Resolved Semantic Version.
build_number Build identifier from config/env.
commit_hash Git commit hash from config/env.
branch Branch name from config/env.
environment Laravel application environment.
channel Release channel: stable, beta, or rc.
changelog_url Optional changelog reference URL.

Example:

$metadata = release_metadata();

$metadata->version();
$metadata->buildNumber();
$metadata->commitHash();
$metadata->branch();
$metadata->environment();
$metadata->channel();
$metadata->changelogUrl();
$metadata->toArray();

Compatibility Governance

API client compatibility checks. Configure a minimum supported client version:

'compatibility' => [
    'enabled' => true,
    'minimum_client_version' => '2.0.0',
    'client_version_header' => 'X-Client-Version',
    'allow_missing_client_version' => false,
    'incompatible_status' => 426,
    'message' => 'Client version is no longer supported.',
],

Attach the middleware to API routes:

use Illuminate\Support\Facades\Route;

Route::middleware('release.compatible')->group(function () {
    Route::get('/api/profile', ProfileController::class);
});

Compatible clients pass through when their header satisfies the configured minimum:

X-Client-Version: 2.1.0

Incompatible clients receive a structured JSON response:

{
    "error": {
        "code": "incompatible_client",
        "details": {
            "compatible": false,
            "reason": "minimum_version_not_satisfied",
            "message": "Client version is no longer supported.",
            "client_version": "1.9.9",
            "minimum_client_version": "2.0.0",
            "app_version": "1.2.3",
            "channel": "stable",
            "changelog_url": "https://example.com/changelog"
        }
    }
}

You can also use the service directly:

use Sunnynath\LaravelReleaseManager\Services\CompatibilityManager;

$result = app(CompatibilityManager::class)->check('2.1.0');

$result->compatible();
$result->toArray();

Artisan Commands

release:show

Displays the resolved application release metadata.

php artisan release:show
php artisan release:show --json

release:bump

Bumps the resolved version and writes it to the configured version file.

php artisan release:bump patch
php artisan release:bump minor
php artisan release:bump major
php artisan release:bump patch --pre-release=beta.1
php artisan release:bump patch --build=20260517.1
php artisan release:bump patch --dry-run
php artisan release:bump patch --json
php artisan release:bump patch --ci

Supported bump parts:

Part Example
patch 1.2.3 to 1.2.4
minor 1.2.3 to 1.3.0
major 1.2.3 to 2.0.0

release:sync

Finds the latest valid Semantic Version from Git tags and writes it to the configured version file.

php artisan release:sync
php artisan release:sync --dry-run
php artisan release:sync --json
php artisan release:sync --ci

release:tag

Previews or creates a Git tag for a release version.

php artisan release:tag
php artisan release:tag 1.2.3
php artisan release:tag 1.2.3 --create
php artisan release:tag 1.2.3 --create --lightweight
php artisan release:tag 1.2.3 --create --message="Release 1.2.3"
php artisan release:tag 1.2.3 --dry-run
php artisan release:tag 1.2.3 --json
php artisan release:tag 1.2.3 --ci

By default, release:tag is a preview. Pass --create to actually create the Git tag. The options --create and --dry-run cannot be used together.

release:doctor

Checks release manager configuration and Git automation readiness. This is the fastest way to catch malformed source priority, invalid Semantic Versions, invalid release channels, missing Git state, and command setup issues.

php artisan release:doctor
php artisan release:doctor --json
php artisan release:doctor --ci

All release automation commands support --json and --ci for CI/CD pipelines. The --ci option implies machine-readable JSON output and deterministic exit codes.

In CI mode, release:doctor fails only for critical problems such as invalid configuration or an unresolvable release version. Non-critical readiness warnings, such as optional Git details not being available, are reported in JSON without failing the process.

Laravel About Command

The package registers release details with Laravel's built-in about command:

php artisan about
php artisan about --json

The Laravel Release Manager section includes:

  • Package name and package version
  • Resolved application version
  • Release channel
  • Build number, commit hash, and branch
  • Minimum supported client version
  • Cache and metadata endpoint status

Audit Logging

Release-changing commands write compact audit log entries after real changes:

Command Audit action
release:bump release.bumped
release:sync release.synced
release:tag --create release.tagged

Dry runs are not logged. Disable logging with:

RELEASE_AUDIT_ENABLED=false

HTTP Headers

Attach the middleware to routes that should expose release headers:

use Illuminate\Support\Facades\Route;

Route::middleware('release.headers')->group(function () {
    Route::get('/health', HealthCheckController::class);
});

The middleware adds:

Header Value
X-App-Version Resolved application version.
X-App-Build Configured build number.
X-Git-Commit Configured commit hash.

You may also reference the middleware class directly:

use Sunnynath\LaravelReleaseManager\Http\Middleware\AddReleaseHeaders;

Route::middleware(AddReleaseHeaders::class)->get('/health', HealthCheckController::class);

Optional Metadata Endpoint

The JSON metadata endpoint is disabled by default because release metadata can be operationally sensitive.

Enable it in config/release-manager.php:

'http' => [
    'endpoint' => [
        'enabled' => true,
        'path' => 'release',
        'middleware' => [],
    ],
],

Then request:

GET /release

Example response:

{
    "data": {
        "version": "1.2.3",
        "build_number": "20260517.1",
        "commit_hash": "abc1234",
        "branch": "main",
        "environment": "production",
        "channel": "stable",
        "changelog_url": "https://example.com/changelog"
    }
}

For production APIs, protect this endpoint with your own middleware when needed:

'middleware' => ['auth:sanctum'],

Blade Usage

Render the current application version:

@appVersion

Example footer:

<footer>
    Version @appVersion
</footer>

Facade And Helpers

Helpers:

release_version();   // string
release_metadata();  // ReleaseMetadata

Facade:

use Sunnynath\LaravelReleaseManager\Facades\Release;

Release::version();
Release::metadata();

CI/CD Examples

Bump a patch version and create a tag:

php artisan release:bump patch --ci
php artisan release:tag --create --ci

Sync the application version from Git tags:

php artisan release:sync --ci

Read machine-friendly metadata:

php artisan release:show --json
php artisan release:doctor --json

Contributing

Contributions are welcome through pull requests.

The usual workflow is to fork the repository, create a branch in your fork, make the change, and open a pull request back to this repository. Contributors do not need branches inside the main repository.

git clone https://github.com/metaphorized-soul/laravel-release-manager.git
cd laravel-release-manager

git checkout -b fix/some-bug

# make changes

composer test
composer validate --strict

git add .
git commit -m "Fix some bug"
git push origin fix/some-bug

Then open a pull request from your fork. Please include a short explanation of the change and tests when the change affects behavior.

Testing

From the package root:

composer install
composer test

Run Composer validation before tagging a release:

composer validate --strict

License

Laravel Release Manager is open-sourced software licensed under the MIT license.