mirror of
https://github.com/koel/koel
synced 2024-11-10 06:34:14 +00:00
feat: add a command to release Koel
This commit is contained in:
parent
618929e9bf
commit
0b99f3a1f3
4 changed files with 219 additions and 38 deletions
149
app/Console/Commands/ReleaseCommand.php
Normal file
149
app/Console/Commands/ReleaseCommand.php
Normal file
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Process;
|
||||
use PHLAK\SemVer\Version;
|
||||
use Throwable;
|
||||
|
||||
use function Laravel\Prompts\error;
|
||||
use function Laravel\Prompts\info;
|
||||
use function Laravel\Prompts\note;
|
||||
use function Laravel\Prompts\select;
|
||||
use function Laravel\Prompts\text;
|
||||
use function Laravel\Prompts\warning;
|
||||
|
||||
class ReleaseCommand extends Command
|
||||
{
|
||||
protected $signature
|
||||
= 'koel:release {version? : The version to release, or "patch", "minor", "major" for auto-increment}';
|
||||
protected $description = 'Tag and release a new version of Koel';
|
||||
|
||||
private Version $currentVersion;
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
self::ensureCleanWorkingDirectory();
|
||||
|
||||
$this->getCurrentVersion();
|
||||
|
||||
$releaseVersion = match ($this->argument('version')) {
|
||||
'patch' => (clone $this->currentVersion)->incrementPatch()->prefix(),
|
||||
'minor' => (clone $this->currentVersion)->incrementMinor()->prefix(),
|
||||
'major' => (clone $this->currentVersion)->incrementMajor()->prefix(),
|
||||
null => $this->acquireReleaseVersionInteractively(),
|
||||
default => self::tryParseVersion($this->argument('version')) ?? $this->acquireReleaseVersionInteractively(),
|
||||
};
|
||||
|
||||
try {
|
||||
$this->release($releaseVersion);
|
||||
} catch (Throwable $e) {
|
||||
error($e->getMessage());
|
||||
warning('Something went wrong. Double-check the working directory and maybe try again.');
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
private function release(string $version): void
|
||||
{
|
||||
// Ensure the version is prefixed.
|
||||
$version = Version::parse($version)->prefix();
|
||||
|
||||
info("Releasing version $version...");
|
||||
|
||||
File::put(base_path('.version'), $version);
|
||||
|
||||
$gitCommands = [
|
||||
'add .',
|
||||
"commit -m 'chore(release): bump version to $version'",
|
||||
'push',
|
||||
"tag $version",
|
||||
'tag latest -f',
|
||||
'push origin --tags -f',
|
||||
'checkout release',
|
||||
'pull',
|
||||
'merge master',
|
||||
'push',
|
||||
];
|
||||
|
||||
foreach ($gitCommands as $command) {
|
||||
$this->components->task("Executing `git $command`", static fn () => self::runOkOrThrow("git $command"));
|
||||
}
|
||||
|
||||
info("Success! The new version $version has been tagged.");
|
||||
info('Now go to https://github.com/koel/koel/releases and finish the draft release notes.');
|
||||
}
|
||||
|
||||
private function acquireReleaseVersionInteractively(): string
|
||||
{
|
||||
$patchVersion = (clone $this->currentVersion)->incrementPatch()->prefix();
|
||||
|
||||
$suggestedVersions = [
|
||||
$patchVersion => 'Patch',
|
||||
(clone $this->currentVersion)->incrementMinor()->prefix() => 'Minor',
|
||||
(clone $this->currentVersion)->incrementMajor()->prefix() => 'Major',
|
||||
];
|
||||
|
||||
$options = [];
|
||||
|
||||
foreach ($suggestedVersions as $version => $name) {
|
||||
$options[$version] = "$name -> $version";
|
||||
}
|
||||
|
||||
$options['custom'] = 'Custom';
|
||||
|
||||
$selected = select(
|
||||
label: 'What are we releasing?',
|
||||
options: $options,
|
||||
default: $patchVersion,
|
||||
);
|
||||
|
||||
if ($selected === 'custom') {
|
||||
$selected = text(
|
||||
label: 'Enter the version you want to release',
|
||||
placeholder: $patchVersion,
|
||||
required: true,
|
||||
validate: static fn (string $value) => self::tryParseVersion($value)
|
||||
? null
|
||||
: 'Invalid version format',
|
||||
);
|
||||
}
|
||||
|
||||
return Version::parse($selected)->prefix();
|
||||
}
|
||||
|
||||
private static function tryParseVersion(string $version): ?string
|
||||
{
|
||||
try {
|
||||
return Version::parse($version)->prefix();
|
||||
} catch (Throwable) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function getCurrentVersion(): void
|
||||
{
|
||||
$this->currentVersion = new Version(File::get(base_path('.version')));
|
||||
|
||||
note('Current version: ' . $this->currentVersion->prefix());
|
||||
}
|
||||
|
||||
private static function ensureCleanWorkingDirectory(): void
|
||||
{
|
||||
if (Process::run('git status --porcelain')->output()) {
|
||||
error('Your working directly is not clean. Please commit or stash your changes before proceeding.');
|
||||
|
||||
exit(self::FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
private static function runOkOrThrow(string $command): void
|
||||
{
|
||||
throw_unless(Process::forever()->run($command)->successful());
|
||||
}
|
||||
}
|
|
@ -55,7 +55,9 @@
|
|||
"fakerphp/faker": "^1.13",
|
||||
"slevomat/coding-standard": "^7.0",
|
||||
"laravel/tinker": "^2.9",
|
||||
"larastan/larastan": "^2.9"
|
||||
"larastan/larastan": "^2.9",
|
||||
"phlak/semver": "^5.0",
|
||||
"laravel/prompts": "^0.1.25"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-zip": "Allow downloading multiple songs as Zip archives"
|
||||
|
|
74
composer.lock
generated
74
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "9da46e14c758c109ce78f30cbaa63a09",
|
||||
"content-hash": "518f509cd591617642652600dccb90c6",
|
||||
"packages": [
|
||||
{
|
||||
"name": "algolia/algoliasearch-client-php",
|
||||
|
@ -2635,16 +2635,16 @@
|
|||
},
|
||||
{
|
||||
"name": "laravel/prompts",
|
||||
"version": "v0.1.19",
|
||||
"version": "v0.1.25",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/prompts.git",
|
||||
"reference": "0ab75ac3434d9f610c5691758a6146a3d1940c18"
|
||||
"reference": "7b4029a84c37cb2725fc7f011586e2997040bc95"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/prompts/zipball/0ab75ac3434d9f610c5691758a6146a3d1940c18",
|
||||
"reference": "0ab75ac3434d9f610c5691758a6146a3d1940c18",
|
||||
"url": "https://api.github.com/repos/laravel/prompts/zipball/7b4029a84c37cb2725fc7f011586e2997040bc95",
|
||||
"reference": "7b4029a84c37cb2725fc7f011586e2997040bc95",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2684,11 +2684,12 @@
|
|||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Add beautiful and user-friendly forms to your command-line applications.",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/prompts/issues",
|
||||
"source": "https://github.com/laravel/prompts/tree/v0.1.19"
|
||||
"source": "https://github.com/laravel/prompts/tree/v0.1.25"
|
||||
},
|
||||
"time": "2024-04-16T14:20:35+00:00"
|
||||
"time": "2024-08-12T22:06:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/sanctum",
|
||||
|
@ -10911,6 +10912,65 @@
|
|||
},
|
||||
"time": "2022-02-21T01:04:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phlak/semver",
|
||||
"version": "5.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHLAK/SemVer.git",
|
||||
"reference": "3c4db3a7953ac414b947c183548b6a5b825da738"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHLAK/SemVer/zipball/3c4db3a7953ac414b947c183548b6a5b825da738",
|
||||
"reference": "3c4db3a7953ac414b947c183548b6a5b825da738",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^8.0 || ^8.1 || ^8.2 || 8.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phlak/coding-standards": "^2.0",
|
||||
"phpstan/phpstan": "^1.11",
|
||||
"phpunit/phpunit": "^9.0 || ^10.0",
|
||||
"yoast/phpunit-polyfills": "^2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Support/helpers.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"PHLAK\\SemVer\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Chris Kankiewicz",
|
||||
"email": "Chris@ChrisKankiewicz.com"
|
||||
}
|
||||
],
|
||||
"description": "Semantic versioning helper library",
|
||||
"support": {
|
||||
"issues": "https://github.com/PHLAK/SemVer/issues",
|
||||
"source": "https://github.com/PHLAK/SemVer/tree/5.0.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sponsors/PHLAK",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://paypal.me/ChrisKankiewicz",
|
||||
"type": "paypal"
|
||||
}
|
||||
],
|
||||
"time": "2024-08-02T16:57:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-mock/php-mock",
|
||||
"version": "2.5.0",
|
||||
|
|
30
tag.sh
30
tag.sh
|
@ -1,30 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [[ $(git status --porcelain) ]]; then
|
||||
echo 'ERROR: Please commit all changes before tagging a new version.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo 'ERROR: You must supply a version number.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TAG=$1
|
||||
echo "$TAG" > .version
|
||||
|
||||
git -c color.ui=always add .
|
||||
git -c color.ui=always commit -m "chore(release): bump version to ${TAG}"
|
||||
git -c color.ui=always push
|
||||
git -c color.ui=always tag "$TAG"
|
||||
git -c color.ui=always tag latest -f
|
||||
git -c color.ui=always push --tags -f
|
||||
|
||||
# Update and push the release branch so that documentation is updated
|
||||
echo "Update the release branch"
|
||||
git -c color.ui=always checkout release
|
||||
git -c color.ui=always pull
|
||||
git -c color.ui=always merge master
|
||||
git -c color.ui=always push
|
||||
|
||||
echo "${TAG} tagged. Now go to https://github.com/koel/koel/releases and finish the draft release."
|
Loading…
Reference in a new issue