fix(api): remove broken Coolify cron-worker auto-deploy (#389)
## Summary The Coolify-based auto-deployment of a separate `cron` worker app after every API deploy was never reliable. This PR removes the ~800 lines of dead auto-deploy logic from `release_manager.php` while keeping the underlying cron mechanism (`cron_worker.php`, `cron_scheduler.php`, the docker-compose `cron-worker` service) intact. ## Changes - **`release_manager.php`** (-818 lines) - Removed 19 private methods: `deployCronWorker*`, `cronWorker*`, `cronWorkerAutoprovision*`, etc. - Removed 3 constants: `CRON_WORKER_APP`, `CRON_WORKER_START_COMMAND`, `CRON_WORKER_DESIRED_COUNT` - Kept `cronWorkerStatus()` but rewrote as a direct DB query (no Coolify dependency) - **`tests/Unit/ReleaseManager/ReleaseManagerTest.php`** (-208 lines, removed 9 cron-worker tests) - **`tests/Unit/Cron/CronWorkerWiringTest.php`** (rewritten — now asserts removed wiring is GONE) - **`docs/CRON_PLAN.md`** (new — comprehensive plan) ## What replaced the broken auto-deploy - The cron worker runs as part of the main API docker-compose stack (the `cron-worker` service is unchanged) - New verification cron `1bb56ba8-2f3e-4bea-baa2-39801ea88ea8` runs `/workspace/scripts/verify-api-cron.py` every 5 min - Alerts to Slack #ai-daily (`C0AM3E43249`) if no fresh heartbeat in 10+ min ## Test results - 4/4 cron tests pass - 54/54 ReleaseManager tests pass - Full Unit suite: **1279 passed** (same 7 pre-existing failures on master, unchanged) - `php -l` passes on all modified files ## Plan See `docs/CRON_PLAN.md` for the full audit, plan, and acceptance criteria. 🤖 Generated with [OpenClaw](https://docs.openclaw.ai) --------- Co-authored-by: bugfix <bugfix@truckwash.local> Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
co-authored by
bugfix
openhands
parent
4c6b60c9f2
commit
935b2d58ce
@@ -1,9 +1,14 @@
|
||||
<?php
|
||||
|
||||
// Test that the cron mechanism is properly wired. The Coolify auto-deploy logic
|
||||
// was removed from release_manager.php 2026-08-17, so this test no longer asserts
|
||||
// anything about cron worker deployment. The actual cron mechanism
|
||||
// (cron_worker.php, cron_scheduler.php, cli.php, cronRoute.php) is unchanged.
|
||||
|
||||
$cronAppRoot = dirname(__DIR__, 3);
|
||||
require_once $cronAppRoot . '/classes/cron_worker.php';
|
||||
|
||||
it('wires cron workers through schema, CLI, scheduler, and superuser routes', function (): void {
|
||||
it('wires cron workers through schema, scheduler, CLI, and routes', function (): void {
|
||||
$appRoot = dirname(__DIR__, 3);
|
||||
$repoRoot = getenv('PLENO_REPO_ROOT_FOR_TESTS') ?: dirname($appRoot, 3);
|
||||
$schema = file_get_contents($appRoot . '/classes/cron_schema_bootstrap.php');
|
||||
@@ -11,12 +16,6 @@ it('wires cron workers through schema, CLI, scheduler, and superuser routes', fu
|
||||
$scheduler = file_get_contents($appRoot . '/classes/cron_scheduler.php');
|
||||
$cli = file_get_contents($appRoot . '/cli.php');
|
||||
$route = file_get_contents($appRoot . '/routes/cronRoute.php');
|
||||
$manager = file_get_contents($appRoot . '/classes/release_manager.php');
|
||||
$composeFiles = [
|
||||
$repoRoot . '/docker-compose.yml',
|
||||
$repoRoot . '/docker-compose.example.yml',
|
||||
$repoRoot . '/docker-compose.prod.standalone.yml',
|
||||
];
|
||||
|
||||
expect($schema)->toContain('CREATE TABLE IF NOT EXISTS cron_worker_state');
|
||||
expect($schema)->toContain('last_heartbeat_at');
|
||||
@@ -47,29 +46,24 @@ it('wires cron workers through schema, CLI, scheduler, and superuser routes', fu
|
||||
expect($cli)->toContain('new \\classes\\cron_worker()');
|
||||
|
||||
expect($route)->toContain('/superuser/cron/workers');
|
||||
expect($route)->toContain('/superuser/cron/workers/deploy');
|
||||
expect($route)->toContain('$response->success($result, 202)');
|
||||
expect($route)->toContain('queueTaskRun(');
|
||||
expect($route)->toContain('$response->success($run, 202)');
|
||||
expect($route)->toContain('superuser_cron_view');
|
||||
expect($route)->toContain('superuser_cron_manage');
|
||||
expect($route)->toContain('superuser_coolify_manage');
|
||||
});
|
||||
|
||||
expect($manager)->toContain("private const CRON_WORKER_APP = 'cron'");
|
||||
expect($manager)->toContain("private const CRON_WORKER_START_COMMAND = 'php index.php run cron-worker'");
|
||||
expect($manager)->toContain('deployCronWorkerAfterApiDeployment');
|
||||
expect($manager)->toContain('deployment_kind = \'cron_worker\'');
|
||||
expect($manager)->toContain('createCronWorkerDeploymentRecord');
|
||||
expect($manager)->toContain('waiting_for_heartbeat');
|
||||
expect($manager)->toContain('cronWorkerAutoprovisionRequired');
|
||||
expect($manager)->toContain('cron_worker_autoprovision_disabled');
|
||||
expect($manager)->toContain('cron_worker_deploy_failed');
|
||||
expect($manager)->toContain('auto_deploy = 0');
|
||||
it('starts the cron-worker service via the docker-compose entrypoint', function (): void {
|
||||
$appRoot = dirname(__DIR__, 3);
|
||||
$repoRoot = getenv('PLENO_REPO_ROOT_FOR_TESTS') ?: dirname($appRoot, 3);
|
||||
$composeFiles = [
|
||||
$repoRoot . '/docker-compose.yml',
|
||||
$repoRoot . '/docker-compose.example.yml',
|
||||
$repoRoot . '/docker-compose.prod.standalone.yml',
|
||||
];
|
||||
|
||||
foreach ($composeFiles as $composeFile) {
|
||||
$compose = file_get_contents($composeFile);
|
||||
expect(str_contains($compose, 'command: ["php", "index.php", "run", "cron-worker"]'))->toBeTrue();
|
||||
expect(str_contains($compose, 'while true; do php index.php run cron; sleep 60; done'))->toBeFalse();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -104,3 +98,18 @@ it('reports consecutive scheduler loops as once-per-minute execution proof', fun
|
||||
$result = $publicWorker->invoke($worker, $row);
|
||||
expect($result['minute_cadence']['verified'])->toBeFalse();
|
||||
});
|
||||
|
||||
it('exposes a cron status endpoint that no longer references Coolify auto-deploy', function (): void {
|
||||
$appRoot = dirname(__DIR__, 3);
|
||||
$manager = file_get_contents($appRoot . '/classes/release_manager.php');
|
||||
// The Coolify auto-deploy constants and methods must be gone
|
||||
expect($manager)->not->toContain("private const CRON_WORKER_APP = 'cron'");
|
||||
expect($manager)->not->toContain("private const CRON_WORKER_START_COMMAND = 'php index.php run cron-worker'");
|
||||
expect($manager)->not->toContain('function deployCronWorker');
|
||||
expect($manager)->not->toContain('function deployCronWorkerAfterApiDeployment');
|
||||
expect($manager)->not->toContain('function cronWorkerAutoprovision');
|
||||
expect($manager)->not->toContain('function cronWorkerHealth');
|
||||
// The cronWorkerStatus method should still exist as a thin DB wrapper
|
||||
expect($manager)->toContain('public function cronWorkerStatus');
|
||||
expect($manager)->toContain("'coolify_auto_deploy_enabled' => false");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user