Clean up stale Coolify API routes
This commit is contained in:
@@ -159,6 +159,11 @@ class coolify_api_client
|
||||
return $this->request('GET', '/applications/' . rawurlencode($uuid) . '/restart');
|
||||
}
|
||||
|
||||
public function stopApplication(string $uuid): array
|
||||
{
|
||||
return $this->request('GET', '/applications/' . rawurlencode($uuid) . '/stop');
|
||||
}
|
||||
|
||||
public function deleteService(string $uuid): array
|
||||
{
|
||||
return $this->request('DELETE', '/services/' . rawurlencode($uuid));
|
||||
|
||||
@@ -1435,6 +1435,7 @@ class release_manager
|
||||
}
|
||||
|
||||
$expectedCommit = self::normalizeCommitSha((string)($gateInput['expected_commit'] ?? ''));
|
||||
$enforceExpectedCommit = $expectedCommit !== '' && !$this->releaseGateAutoSyncRequested($gateInput);
|
||||
$checked = [];
|
||||
try {
|
||||
foreach ($gateInput['api_ping_paths'] as $path) {
|
||||
@@ -1444,7 +1445,7 @@ class release_manager
|
||||
throw new RuntimeException(sprintf('%s returned success=false.', $path));
|
||||
}
|
||||
$actualCommit = $this->releaseGateApiPayloadCommitSha($payload);
|
||||
if ($expectedCommit !== '' && !$this->releaseGateCommitMatches($actualCommit, $expectedCommit)) {
|
||||
if ($enforceExpectedCommit && !$this->releaseGateCommitMatches($actualCommit, $expectedCommit)) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'%s returned commit %s, expected %s.',
|
||||
$path,
|
||||
@@ -6257,6 +6258,7 @@ class release_manager
|
||||
}
|
||||
|
||||
$deployment = $client->deployResource($serviceUuid, $this->releaseCoolifyForceRebuild($context));
|
||||
$previousApplications = $this->stopCoolifyPreviousApplications($client, $context, $serviceUuid);
|
||||
return [
|
||||
'service_uuid' => $serviceUuid,
|
||||
'resource_type' => $resourceType,
|
||||
@@ -6266,9 +6268,76 @@ class release_manager
|
||||
'updated' => self::redactPayload($update ?? []),
|
||||
'runtime_env' => $runtimeEnvUpdate,
|
||||
'deployment' => self::redactPayload($deployment),
|
||||
'previous_applications' => self::redactPayload($previousApplications),
|
||||
];
|
||||
}
|
||||
|
||||
private function stopCoolifyPreviousApplications(coolify_api_client $client, array $context, string $activeUuid): array
|
||||
{
|
||||
$stopped = [];
|
||||
foreach ($this->releaseCoolifyPreviousApplicationUuids($context, $activeUuid) as $uuid) {
|
||||
try {
|
||||
$stopped[] = [
|
||||
'uuid' => $uuid,
|
||||
'status' => 'stop_requested',
|
||||
'result' => $client->stopApplication($uuid),
|
||||
];
|
||||
} catch (Throwable $throwable) {
|
||||
$stopped[] = [
|
||||
'uuid' => $uuid,
|
||||
'status' => 'warning',
|
||||
'error' => $throwable->getMessage(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $stopped;
|
||||
}
|
||||
|
||||
private function releaseCoolifyPreviousApplicationUuids(array $context, string $activeUuid): array
|
||||
{
|
||||
$values = [];
|
||||
foreach ([
|
||||
'coolify_previous_application_uuid',
|
||||
'coolify_previous_artifact_app_uuid',
|
||||
'coolify_previous_artifact_application_uuid',
|
||||
'previous_application_uuid',
|
||||
'previous_app_uuid',
|
||||
] as $key) {
|
||||
if (is_scalar($context[$key] ?? null)) {
|
||||
$values[] = (string)$context[$key];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ([
|
||||
'coolify_previous_application_uuids',
|
||||
'coolify_previous_artifact_app_uuids',
|
||||
'previous_application_uuids',
|
||||
'previous_app_uuids',
|
||||
] as $key) {
|
||||
if (!is_array($context[$key] ?? null)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($context[$key] as $value) {
|
||||
if (is_scalar($value)) {
|
||||
$values[] = (string)$value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$activeUuid = trim($activeUuid);
|
||||
$uuids = [];
|
||||
foreach ($values as $value) {
|
||||
$uuid = trim((string)$value);
|
||||
if ($uuid === '' || $uuid === $activeUuid || in_array($uuid, $uuids, true)) {
|
||||
continue;
|
||||
}
|
||||
$uuids[] = $uuid;
|
||||
}
|
||||
|
||||
return $uuids;
|
||||
}
|
||||
|
||||
private function updateCoolifyReleaseRuntimeEnv(coolify_api_client $client, string $resourceUuid, string $resourceType, array $target, array $context): ?array
|
||||
{
|
||||
$env = $this->releaseCoolifyRuntimeEnv($target, $context);
|
||||
|
||||
@@ -1010,6 +1010,7 @@ it('defines release manager schema, routes, permissions, and system-status integ
|
||||
expect($manager)->toContain('createService');
|
||||
expect($manager)->toContain('updateService');
|
||||
expect(file_get_contents(app_path('classes/coolify_api_client.php')))->toContain('updateApplicationEnvsBulk');
|
||||
expect(file_get_contents(app_path('classes/coolify_api_client.php')))->toContain('stopApplication');
|
||||
expect($manager)->toContain('channel_presets');
|
||||
expect($manager)->toContain('target_presets');
|
||||
|
||||
@@ -1400,6 +1401,27 @@ it('resolves release deployment endpoints from manual overrides, URLs, health ch
|
||||
]))->toBe('https://gateway.example.test/beta/frontend');
|
||||
});
|
||||
|
||||
it('collects previous Coolify application UUIDs for stale route cleanup', function (): void {
|
||||
$manager = new release_manager();
|
||||
$previousApplications = new ReflectionMethod(release_manager::class, 'releaseCoolifyPreviousApplicationUuids');
|
||||
$previousApplications->setAccessible(true);
|
||||
|
||||
expect($previousApplications->invoke($manager, [
|
||||
'coolify_previous_artifact_app_uuid' => 'old-artifact-app',
|
||||
'coolify_previous_application_uuid' => 'old-application',
|
||||
'coolify_previous_application_uuids' => [
|
||||
'old-application',
|
||||
'active-application',
|
||||
'other-old-application',
|
||||
'',
|
||||
],
|
||||
], 'active-application'))->toBe([
|
||||
'old-application',
|
||||
'old-artifact-app',
|
||||
'other-old-application',
|
||||
]);
|
||||
});
|
||||
|
||||
it('redacts GitHub access metadata from public release versions', function (): void {
|
||||
$manager = new release_manager();
|
||||
$publicVersion = new ReflectionMethod(release_manager::class, 'publicVersion');
|
||||
|
||||
Reference in New Issue
Block a user