184 lines
6.0 KiB
PHP
184 lines
6.0 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands {
|
|
if (!function_exists(__NAMESPACE__ . '\\file_get_contents')) {
|
|
function file_get_contents($path): string|false
|
|
{
|
|
if (!empty($GLOBALS['version_release_file_get_contents_false']) && str_ends_with($path, 'CHANGELOG.md')) {
|
|
return false;
|
|
}
|
|
|
|
return \file_get_contents($path);
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace {
|
|
use App\Console\Commands\VersionRelease;
|
|
use App\Models\Setting;
|
|
use Illuminate\Support\Facades\Artisan;
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
function withChangelogBackup(callable $callback): void
|
|
{
|
|
$path = base_path('CHANGELOG.md');
|
|
$had = file_exists($path);
|
|
$original = $had ? file_get_contents($path) : null;
|
|
|
|
try {
|
|
$callback($path);
|
|
} finally {
|
|
if ($had) {
|
|
file_put_contents($path, (string) $original);
|
|
} elseif (file_exists($path)) {
|
|
unlink($path);
|
|
}
|
|
}
|
|
}
|
|
|
|
function setGiteaEnvForRelease(): void
|
|
{
|
|
putenv('GITEA_TOKEN=token');
|
|
putenv('GITEA_OWNER=owner');
|
|
putenv('GITEA_REPO=repo');
|
|
putenv('GITEA_API_BASE=https://git.example.test/api/v1');
|
|
putenv('GITEA_PRERELEASE=false');
|
|
}
|
|
|
|
it('fails when version missing', function (): void {
|
|
Setting::where('key', 'version')->delete();
|
|
|
|
$exitCode = Artisan::call('version:release');
|
|
expect($exitCode)->toBe(1);
|
|
});
|
|
|
|
it('fails when gitea config missing', function (): void {
|
|
Setting::updateOrCreate(['key' => 'version'], ['value' => '1.2.3']);
|
|
putenv('GITEA_TOKEN');
|
|
putenv('GITEA_OWNER');
|
|
putenv('GITEA_REPO');
|
|
|
|
$exitCode = Artisan::call('version:release');
|
|
expect($exitCode)->toBe(1);
|
|
});
|
|
|
|
it('creates release successfully with changelog body', function (): void {
|
|
Setting::updateOrCreate(['key' => 'version'], ['value' => '1.2.3']);
|
|
setGiteaEnvForRelease();
|
|
|
|
withChangelogBackup(function (string $path): void {
|
|
file_put_contents($path, "# Changelog\n\n## 1.2.3\n- Added thing\n\n## 1.2.2\n- Old\n");
|
|
|
|
Http::fake([
|
|
'https://git.example.test/api/v1/repos/owner/repo/releases' => Http::response(['id' => 1], 201),
|
|
]);
|
|
|
|
$exitCode = Artisan::call('version:release');
|
|
expect($exitCode)->toBe(0);
|
|
|
|
Http::assertSent(function ($request): bool {
|
|
$payload = $request->data();
|
|
return $payload['tag_name'] === 'v1.2.3'
|
|
&& str_contains($payload['body'], 'Added thing');
|
|
});
|
|
});
|
|
});
|
|
|
|
it('fails when create response is error', function (): void {
|
|
Setting::updateOrCreate(['key' => 'version'], ['value' => '1.2.3']);
|
|
setGiteaEnvForRelease();
|
|
|
|
Http::fake([
|
|
'*' => Http::response([], 500),
|
|
]);
|
|
|
|
$exitCode = Artisan::call('version:release');
|
|
expect($exitCode)->toBe(1);
|
|
});
|
|
|
|
it('fails when existing release cannot be fetched', function (): void {
|
|
Setting::updateOrCreate(['key' => 'version'], ['value' => '1.2.3']);
|
|
setGiteaEnvForRelease();
|
|
|
|
Http::fake([
|
|
'https://git.example.test/api/v1/repos/owner/repo/releases' => Http::response([], 409),
|
|
'https://git.example.test/api/v1/repos/owner/repo/releases/tags/v1.2.3' => Http::response([], 500),
|
|
]);
|
|
|
|
$exitCode = Artisan::call('version:release');
|
|
expect($exitCode)->toBe(1);
|
|
});
|
|
|
|
it('fails when existing release has no id', function (): void {
|
|
Setting::updateOrCreate(['key' => 'version'], ['value' => '1.2.3']);
|
|
setGiteaEnvForRelease();
|
|
|
|
Http::fake([
|
|
'https://git.example.test/api/v1/repos/owner/repo/releases' => Http::response([], 409),
|
|
'https://git.example.test/api/v1/repos/owner/repo/releases/tags/v1.2.3' => Http::response(['id' => null], 200),
|
|
]);
|
|
|
|
$exitCode = Artisan::call('version:release');
|
|
expect($exitCode)->toBe(1);
|
|
});
|
|
|
|
it('updates existing release when create conflicts', function (): void {
|
|
Setting::updateOrCreate(['key' => 'version'], ['value' => '1.2.3']);
|
|
setGiteaEnvForRelease();
|
|
|
|
Http::fake([
|
|
'https://git.example.test/api/v1/repos/owner/repo/releases' => Http::response([], 409),
|
|
'https://git.example.test/api/v1/repos/owner/repo/releases/tags/v1.2.3' => Http::response(['id' => 99], 200),
|
|
'https://git.example.test/api/v1/repos/owner/repo/releases/99' => Http::response(['id' => 99], 200),
|
|
]);
|
|
|
|
$exitCode = Artisan::call('version:release');
|
|
expect($exitCode)->toBe(0);
|
|
});
|
|
|
|
it('fails when updating existing release fails', function (): void {
|
|
Setting::updateOrCreate(['key' => 'version'], ['value' => '1.2.3']);
|
|
setGiteaEnvForRelease();
|
|
|
|
Http::fake([
|
|
'https://git.example.test/api/v1/repos/owner/repo/releases' => Http::response([], 422),
|
|
'https://git.example.test/api/v1/repos/owner/repo/releases/tags/v1.2.3' => Http::response(['id' => 99], 200),
|
|
'https://git.example.test/api/v1/repos/owner/repo/releases/99' => Http::response([], 500),
|
|
]);
|
|
|
|
$exitCode = Artisan::call('version:release');
|
|
expect($exitCode)->toBe(1);
|
|
});
|
|
|
|
it('returns default changelog body when file missing', function (): void {
|
|
withChangelogBackup(function (string $path): void {
|
|
if (file_exists($path)) {
|
|
unlink($path);
|
|
}
|
|
|
|
$command = new VersionRelease();
|
|
$ref = new ReflectionMethod($command, 'resolveChangelogBody');
|
|
$ref->setAccessible(true);
|
|
|
|
$body = $ref->invoke($command, '1.2.3');
|
|
expect($body)->toBe('See commit history for details.');
|
|
});
|
|
});
|
|
|
|
it('returns default changelog body when read fails', function (): void {
|
|
withChangelogBackup(function (string $path): void {
|
|
file_put_contents($path, "# Changelog\n\n## 1.2.3\n- Something\n");
|
|
$GLOBALS['version_release_file_get_contents_false'] = true;
|
|
|
|
$command = new VersionRelease();
|
|
$ref = new ReflectionMethod($command, 'resolveChangelogBody');
|
|
$ref->setAccessible(true);
|
|
|
|
$body = $ref->invoke($command, '1.2.3');
|
|
expect($body)->toBe('See commit history for details.');
|
|
|
|
$GLOBALS['version_release_file_get_contents_false'] = false;
|
|
});
|
|
});
|
|
}
|