woohoolabs/releaser
Lightweight CLI release tool for open-source projects. Runs in a Git repository to bump SemVer versions and create signed Git tags (GPG). Install via Composer and execute ./vendor/bin/releaser to publish a new release.
Installation:
composer require woohoolabs/releaser
Add the service provider to config/app.php:
'providers' => [
// ...
Woohoolabs\Releaser\ReleaserServiceProvider::class,
],
Publish Config:
php artisan vendor:publish --provider="Woohoolabs\Releaser\ReleaserServiceProvider" --tag="config"
Edit config/releaser.php to match your project’s GitHub/GitLab repo, changelog paths, and versioning rules.
First Release:
php artisan releaser:release --dry-run
Verify the changelog and version bump before committing.
Update Changelog:
php artisan releaser:changelog "Fix typo in README"
This appends the commit message to the Unreleased section of your changelog (e.g., CHANGELOG.md).
Release:
php artisan releaser:release --patch
v1.0.1).New in 1.2.0: Disable tag signing with --no-signing:
php artisan releaser:release --patch --no-signing
Pre-Commit Hooks:
Use releaser:changelog in a pre-commit hook to auto-categorize commits (e.g., feat:, fix:).
Example Git hook:
# .git/hooks/pre-commit
#!/bin/bash
if [[ "$(git diff --cached --name-only)" =~ CHANGELOG.md$ ]]; then
exit 0
else
php artisan releaser:changelog "$(git log -1 --pretty=%B)"
fi
CI/CD Pipeline:
Trigger releases on merged PRs with semantic labels (e.g., major, minor):
# .github/workflows/release.yml
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: composer install
- run: php artisan releaser:release --${{ github.event.pull_request.labels.* }} --no-signing
Custom Versioning:
Override default semantic versioning by extending the Woohoolabs\Releaser\Versioner class:
// app/Versioners/CustomVersioner.php
namespace App\Versioners;
use Woohoolabs\Releaser\Versioner;
class CustomVersioner extends Versioner {
protected function getVersion(): string {
return 'v'.parent::getVersion().'-beta';
}
}
Bind it in config/releaser.php:
'versioner' => App\Versioners\CustomVersioner::class,
Changelog Templates:
Customize the changelog template in config/releaser.php:
'changelog' => [
'template' => '## {{ .Version }} ({{ .Date }})',
'sections' => [
'Features' => 'feat:',
'Bug Fixes' => 'fix:',
],
],
Dry Runs:
Always use --dry-run before actual releases to preview changes:
php artisan releaser:release --dry-run --minor --no-signing
Multi-Repository Projects:
Use the --repo flag to manage releases for sub-packages:
php artisan releaser:release --repo=packages/auth --patch --no-signing
Changelog Conflicts:
git merge --no-ff to preserve changelog history or stash changes before releasing.Tag Collisions:
v1.0.0) may conflict with auto-generated ones.config/releaser.php to prefix tags:
'tag_prefix' => 'release/',
GitHub API Rate Limits:
.env:
GITHUB_TOKEN=your_token_here
Tag Signing Overhead:
--no-signing in CI/CD environments where signing isn’t required:
php artisan releaser:release --patch --no-signing
Verbose Output: Enable debug mode for detailed logs:
php artisan releaser:release --debug --patch --no-signing
Commit Message Parsing:
config/releaser.php under commit_types.'commit_types' => [
'feat' => 'feature',
'fix' => 'bugfix',
'docs' => 'documentation',
'refactor' => 'refactor',
],
Version File Issues:
composer.json has a valid version field (e.g., "version": "1.0.0").config/releaser.php:
'version_file' => 'version.txt',
Tag Signing Errors:
git config --global user.signingkey YOUR_KEY_ID
--no-signing:
php artisan releaser:release --patch --no-signing
Custom Release Actions:
Extend the Woohoolabs\Releaser\Release class to add post-release tasks (e.g., Slack notifications):
// app/Releasers/CustomRelease.php
namespace App\Releasers;
use Woohoolabs\Releaser\Release;
class CustomRelease extends Release {
protected function afterRelease() {
$this->notifySlack();
}
private function notifySlack() {
// Logic to send Slack message
}
}
Bind it in config/releaser.php:
'release_class' => App\Releasers\CustomRelease::class,
Plugin System: Use Laravel’s service container to bind custom logic:
// In a service provider
$this->app->bind(
Woohoolabs\Releaser\Contracts\ReleaseNotifier::class,
App\Services\CustomNotifier::class
);
Webhook Triggers: Create a Laravel route to trigger releases via HTTP:
// routes/api.php
Route::post('/release', function () {
return \Artisan::call('releaser:release', [
'--type' => request('type', 'patch'),
'--dry-run' => true,
'--no-signing' => true,
]);
});
Conditional Signing: Dynamically enable/disable signing based on environment:
// In a custom release class
protected function shouldSignTag(): bool {
return !app()->environment('production') || config('releaser.sign_tags');
}
How can I help you explore Laravel packages today?