false, 'error' => 'Method not allowed'])); } $sig = $_SERVER['HTTP_X_GITEA_SIGNATURE'] ?? ''; $raw = file_get_contents('php://input'); $expected = hash_hmac('sha256', $raw, DEPLOY_SECRET); if (!hash_equals($expected, $sig)) { http_response_code(403); exit(json_encode(['ok' => false, 'error' => 'Bad signature'])); } $payload = json_decode($raw, true); $ref = $payload['ref'] ?? ''; if ($ref !== 'refs/heads/main') { echo json_encode(['ok' => true, 'skipped' => true, 'ref' => $ref]); exit; } // Fire-and-forget — respond immediately, deploy runs in background $logFile = LOG_FILE; $script = DEPLOY_SCRIPT; $cmd = "bash {$script} >> {$logFile} 2>&1"; if (function_exists('proc_open')) { $desc = [['pipe', 'r'], ['file', $logFile, 'a'], ['file', $logFile, 'a']]; $proc = proc_open('bash ' . escapeshellarg($script), $desc, $pipes, null, null, ['bypass_shell' => false]); if (is_resource($proc)) proc_close($proc); } else { exec("{$cmd} &"); } echo json_encode(['ok' => true, 'deploying' => true, 'ref' => $ref]);