hopheartsceo / laravel-release-guard
Detect database changes that can break the previous Laravel release during rolling and zero-downtime deployments.
Package info
github.com/hopheartsceo/Laravel-Release-Guard
pkg:composer/hopheartsceo/laravel-release-guard
Requires
- php: ^8.1
- illuminate/console: ^10.0|^11.0|^12.0|^13.0
- illuminate/filesystem: ^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
- nikic/php-parser: ^5.0
- symfony/process: ^6.2|^7.0|^8.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0|^10.0|^11.0
- phpunit/phpunit: ^10.5|^11.5
This package is auto-updated.
Last update: 2026-08-18 10:33:44 UTC
README
Laravel Release Guard is a static deployment compatibility analyzer for Laravel applications.
It checks supported database changes for incompatibilities between the release you are preparing and the application version that is already running during a rolling or zero-downtime deployment.
It does not execute migrations, boot the previous application revision, or run application endpoints.
Instead, it compares the previous Git revision with the candidate working tree and reports evidence-backed compatibility findings.
Why
During a rolling deployment, the old and new application versions may run at the same time.
A migration that is valid for the new code can still break requests handled by the previous release.
For example:
Schema::table('users', function (Blueprint $table) { $table->dropColumn('phone'); });
while the currently deployed release still contains:
User::query() ->where('phone', $phone) ->first();
Laravel Release Guard detects this compatibility problem before deployment.
Installation
Install the package as a development / CI dependency:
composer require --dev hopheartsceo/laravel-release-guard
Laravel package discovery registers the service provider automatically.
Quick Start
Compare the candidate working tree against the revision currently deployed:
php artisan release-guard:check --against=origin/main
You can use any Git revision that resolves to a commit:
php artisan release-guard:check --against=HEAD~1 php artisan release-guard:check --against=v1.2.3 php artisan release-guard:check --against=origin/master
For CI or other machine consumers:
php artisan release-guard:check \
--against=origin/main \
--format=json
How It Works
Git base revision
|
v
Base Laravel database usage index
|
+----------------------+
|
Candidate migration changes |
| |
v v
Schema delta --> Compatibility engine
|
v
Evidence-backed findings
|
v
Console / JSON / CI exit
Laravel Release Guard analyzes the previous application revision directly from Git without checking it out.
Candidate migrations come from changes in the current working tree relative to the selected base revision, including supported untracked migration files.
v0.1 Database Rules
| Code | Rule | Purpose |
|---|---|---|
DB001 |
Dropped column still referenced | Detects a removed column still used by the previous application |
DB002 |
Renamed column still referenced | Detects the previous application still using the old column name |
DB003 |
Dropped table still referenced | Detects a removed table still used by the previous application |
DB004 |
Renamed table still referenced | Detects the previous application still using the old table name |
DB005 |
Required column breaks base writes | Detects newly required columns that supported previous write paths cannot satisfy |
DB006 |
Unanalyzable migration operation | Reports migration operations that cannot be classified safely |
Rules can be individually disabled in configuration.
Findings
Every finding has two important dimensions:
Severity
BLOCKER— deployment compatibility problemWARNING— requires reviewINFO— informational result
Confidence
DEFINITE— supported static evidence establishes the resultPROBABLE— strong evidence exists but certainty is limitedUNKNOWN— the analyzer intentionally cannot prove the result
Laravel Release Guard prefers UNKNOWN over fabricated certainty.
Only a BLOCKER with DEFINITE confidence fails compatibility CI in v0.1.
Exit Codes
The command uses a stable CI-oriented exit-code contract:
| Exit code | Meaning |
|---|---|
0 |
No definite incompatibility was detected within the analyzed scope |
1 |
At least one definite blocker was detected |
2 |
CLI, configuration, Git, or analyzer error |
Exit code 0 does not mean that a deployment has been proven universally safe.
The precise guarantee is:
No incompatible changes detected within the analyzed scope.
Console Output
A successful analysis can look like:
Laravel Release Guard
Base revision: <commit-sha>
Base application files: 42
Candidate migration files: 1
No incompatible changes detected within the analyzed scope.
A detected compatibility problem can look like:
[BLOCKER][DEFINITE][DB001] users.phone — app/Services/UserLookup.php:27
JSON Output
Use:
php artisan release-guard:check \
--against=origin/main \
--format=json
The result is machine-readable:
{
"status": "no_definite_incompatibility_detected",
"base_revision": "<commit-sha>",
"base_application_files": 42,
"candidate_migration_files": 1,
"findings": []
}
When a definite blocker exists, status becomes:
{
"status": "incompatible"
}
Analyzer or Git failures also remain machine-readable when JSON output is requested:
{
"status": "error",
"error": "Analysis failed: ..."
}
Configuration
Publish the configuration file:
php artisan vendor:publish \
--tag=release-guard-config
The default configuration is:
return [ 'paths' => [ 'application' => [ 'app', ], 'migrations' => [ 'database/migrations', ], ], 'confidence' => [ 'fail_on' => 'definite', ], 'rules' => [ 'DB001' => true, 'DB002' => true, 'DB003' => true, 'DB004' => true, 'DB005' => true, 'DB006' => true, ], ];
Application and migration paths can be adjusted for non-standard project layouts.
Conservative Analysis
Laravel Release Guard does not assume that dynamic Laravel behavior is deterministic.
For example, a direct Query Builder insert with a statically known payload can provide strong evidence about the columns being written.
An Eloquent call such as:
User::create([ 'name' => $name, 'email' => $email, ]);
does not necessarily reveal the final SQL insert columns.
Mass-assignment configuration, model defaults, events, mutators, and other model behavior can affect persistence.
For cases like this, Laravel Release Guard intentionally reports uncertainty instead of promoting incomplete evidence to a definite blocker.
The same principle applies to dynamic table names, dynamic column names, dynamic write payloads, and unsupported raw migration operations.
Scope of v0.1
The first release focuses on database compatibility during rolling and zero-downtime Laravel deployments.
It statically analyzes supported Laravel migration operations and supported application database usage patterns.
v0.1 is not intended to prove every possible deployment risk.
In particular, it does not execute application code or migrations, and it does not claim to model every runtime, infrastructure, operational, locking, data-backfill, queue, cache, or serialized-payload compatibility concern.
These are separate deployment concerns and may be addressed by future analysis capabilities.
Git Safety
Laravel Release Guard treats Git input as untrusted analyzer input.
Revision arguments are verified as commits before object lookup.
Working-tree files are restricted to the repository boundary, including protection against traversal, absolute-path access, and symlink escape.
Git failures are exposed through concise analyzer errors rather than raw process command output.
CI Example
A minimal GitHub Actions step can run:
- name: Check rolling deployment compatibility run: | git fetch origin main php artisan release-guard:check --against=origin/main
The command naturally fails the CI job only when a definite blocker is detected or when analysis itself cannot complete.
Requirements
- PHP 8.1 or later
- Laravel 10, 11, 12, or 13
- Git available in the execution environment
Development
Install dependencies:
composer install
Run the complete test suite:
composer test
Design Principle
The project follows one central rule:
Prefer UNKNOWN to invented certainty.
A static deployment analyzer is useful only when teams can trust the distinction between what it knows and what it cannot prove.
License
Laravel Release Guard is open-source software licensed under the MIT License.