coolify/app/Jobs/CleanupGithubRunnerArtifactsJob.php
Andras Bacsai 5c50ab6162 feat(github-runners): improve runner lifecycle and GitHub sync
Add runner execution observability and lifecycle hardening for self-hosted
GitHub Actions runners, including:
- scheduled artifact cleanup job for cached runner tarballs/templates
- workflow_job in_progress handling to mark executions as running
- safer cleanup failure handling and non-functional server fallback
- persisted workflow job HTML URLs with execution "Open" links in UI
- configurable runner group name sync (UI + provisioning + GitHub API)
- webhook events persistence and auto-fix for missing required events
- strict enum/status checks and related model cast/query improvements

Also includes migrations and expanded feature/unit coverage for webhook,
provisioning, cleanup, and runner group/event sync behaviors.
2026-03-03 22:21:13 +01:00

57 lines
2.1 KiB
PHP

<?php
namespace App\Jobs;
use App\Models\GithubRunnerConfig;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class CleanupGithubRunnerArtifactsJob implements ShouldBeEncrypted, ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $timeout = 300;
public $tries = 1;
public function __construct()
{
$this->onQueue('high');
}
public function handle(): void
{
$targets = GithubRunnerConfig::query()
->where('is_enabled', true)
->with('server')
->get()
->filter(fn (GithubRunnerConfig $config) => $config->server?->isFunctional())
->map(fn (GithubRunnerConfig $config): array => [
'server' => $config->server,
'base_dir' => $config->runner_base_dir,
])
->unique(fn (array $target): string => "{$target['server']->id}:{$target['base_dir']}")
->values();
foreach ($targets as $target) {
$baseDir = validateShellSafePath($target['base_dir'], 'runner base directory');
instant_remote_process(static::buildCleanupCommands($baseDir), $target['server'], throwError: false);
}
}
public static function buildCleanupCommands(string $baseDir): array
{
$quotedBaseDir = escapeshellarg($baseDir);
return [
"if [ -d {$quotedBaseDir}/.cache ]; then for arch in x64 arm64; do ls -1t {$quotedBaseDir}/.cache/actions-runner-linux-\${arch}-*.tar.gz 2>/dev/null | tail -n +3 | xargs -r rm -f; done; fi",
"if [ -d {$quotedBaseDir}/.templates ]; then for arch in x64 arm64; do ls -1td {$quotedBaseDir}/.templates/runner-\${arch}-* 2>/dev/null | tail -n +3 | xargs -r rm -rf; done; fi",
"if [ -d {$quotedBaseDir}/.template ]; then for arch in x64 arm64; do ls -1td {$quotedBaseDir}/.template/runner-\${arch}-* 2>/dev/null | tail -n +3 | xargs -r rm -rf; done; fi",
];
}
}