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; }); }); }