114 lines
4.0 KiB
PHP
114 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\Setting;
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
class VersionRelease extends Command
|
|
{
|
|
protected $signature = 'version:release {--prerelease : Mark this release as a prerelease} {--target= : Override target commit (defaults to env GITEA_TARGET_COMMIT or master)}';
|
|
|
|
protected $description = 'Create or update a Gitea release for the current version.';
|
|
|
|
public function handle(): int
|
|
{
|
|
$version = Setting::query()->where('key', 'version')->value('value');
|
|
if (!$version) {
|
|
$this->error('Unable to determine version from settings.');
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$token = env('GITEA_TOKEN');
|
|
$owner = env('GITEA_OWNER');
|
|
$repo = env('GITEA_REPO');
|
|
$apiBase = rtrim((string) env('GITEA_API_BASE', 'https://git.24unix.net/api/v1'), '/');
|
|
$target = $this->option('target') ?: env('GITEA_TARGET_COMMIT', 'master');
|
|
$prerelease = $this->option('prerelease') || filter_var(env('GITEA_PRERELEASE', false), FILTER_VALIDATE_BOOLEAN);
|
|
|
|
if (!$token || !$owner || !$repo) {
|
|
$this->error('Missing Gitea config. Set GITEA_TOKEN, GITEA_OWNER, and GITEA_REPO in .env.');
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$tag = "v{$version}";
|
|
$body = $this->resolveChangelogBody($version);
|
|
|
|
$client = Http::withHeaders([
|
|
'Authorization' => "token {$token}",
|
|
'Accept' => 'application/json',
|
|
]);
|
|
|
|
$payload = [
|
|
'tag_name' => $tag,
|
|
'target_commitish' => $target,
|
|
'name' => $tag,
|
|
'body' => $body,
|
|
'prerelease' => (bool) $prerelease,
|
|
];
|
|
|
|
$createUrl = "{$apiBase}/repos/{$owner}/{$repo}/releases";
|
|
$response = $client->post($createUrl, $payload);
|
|
|
|
if ($response->successful()) {
|
|
$this->info("Release created: {$tag}");
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
if ($response->status() === 409 || $response->status() === 422) {
|
|
$getUrl = "{$apiBase}/repos/{$owner}/{$repo}/releases/tags/{$tag}";
|
|
$existing = $client->get($getUrl);
|
|
if (!$existing->successful()) {
|
|
$this->error('Release already exists, but failed to fetch it for update.');
|
|
return self::FAILURE;
|
|
}
|
|
$id = $existing->json('id');
|
|
if (!$id) {
|
|
$this->error('Release already exists, but no ID was returned.');
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$updateUrl = "{$apiBase}/repos/{$owner}/{$repo}/releases/{$id}";
|
|
$updatePayload = [
|
|
'name' => $tag,
|
|
'body' => $body,
|
|
'prerelease' => (bool) $prerelease,
|
|
'target_commitish' => $target,
|
|
];
|
|
$updated = $client->patch($updateUrl, $updatePayload);
|
|
if ($updated->successful()) {
|
|
$this->info("Release updated: {$tag}");
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
$this->error("Failed to update release: {$updated->status()}");
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$this->error("Failed to create release: {$response->status()}");
|
|
return self::FAILURE;
|
|
}
|
|
|
|
private function resolveChangelogBody(string $version): string
|
|
{
|
|
$path = base_path('CHANGELOG.md');
|
|
if (!is_file($path) || !is_readable($path)) {
|
|
return 'See commit history for details.';
|
|
}
|
|
|
|
$raw = file_get_contents($path);
|
|
if ($raw === false) {
|
|
return 'See commit history for details.';
|
|
}
|
|
|
|
$pattern = '/^##\\s+' . preg_quote($version, '/') . '\\s*\\R(.*?)(?=^##\\s+|\\z)/ms';
|
|
if (preg_match($pattern, $raw, $matches)) {
|
|
$body = trim($matches[1] ?? '');
|
|
return $body !== '' ? $body : 'See commit history for details.';
|
|
}
|
|
|
|
return 'See commit history for details.';
|
|
}
|
|
}
|