Fix deploy webhook: auto-recover from broken .git directory

If git pull fails (corrupted .git), automatically remove the broken
.git dir and re-clone. This prevents the chicken-and-egg problem
where a broken repo state makes the deploy webhook permanently stuck.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mike 2026-03-27 01:35:09 +00:00
parent 629c7d2cef
commit 4a9db0de0a

View file

@ -10,18 +10,47 @@ if ($headerSecret !== $secret) {
exit;
}
// Run git pull directly
// Deploy: clone if needed, otherwise pull (with auto-recovery)
$repoPath = dirname(__DIR__);
$repoUrl = 'https://payfrit:Noorani%401234@git.payfrit.com/payfrit/payfrit-api.git';
$output = [];
$exitCode = 0;
$method = 'unknown';
if (is_dir($repoPath . '/.git')) {
// Try pull first
$method = 'pull';
exec("cd " . escapeshellarg($repoPath) . " && git pull origin main 2>&1", $output, $exitCode);
// Also write trigger file for backward compatibility
// If pull fails, nuke the broken .git and re-clone
if ($exitCode !== 0) {
$method = 'recovery-clone';
$output[] = '--- pull failed, attempting recovery clone ---';
exec("rm -rf " . escapeshellarg($repoPath . '/.git') . " 2>&1");
// Fall through to clone logic below
}
}
if (!is_dir($repoPath . '/.git')) {
// Fresh clone into temp dir, then copy into web root
$method = ($method === 'recovery-clone') ? 'recovery-clone' : 'fresh-clone';
$tmpDir = '/tmp/payfrit-api-clone-' . time();
$cloneOutput = [];
exec("git clone --branch main " . escapeshellarg($repoUrl) . " " . escapeshellarg($tmpDir) . " 2>&1", $cloneOutput, $exitCode);
$output = array_merge($output, $cloneOutput);
if ($exitCode === 0) {
exec("cp -a " . escapeshellarg($tmpDir) . "/. " . escapeshellarg($repoPath) . "/ 2>&1", $output, $exitCode);
exec("rm -rf " . escapeshellarg($tmpDir) . " 2>&1");
}
}
// Write trigger file for backward compatibility
$triggerFile = '/tmp/deploy-payfrit-api.trigger';
file_put_contents($triggerFile, date('Y-m-d H:i:s'));
echo json_encode([
'OK' => $exitCode === 0,
'METHOD' => $method,
'MESSAGE' => $exitCode === 0 ? 'Deploy successful' : 'Deploy failed',
'OUTPUT' => implode("\n", $output),
'TIME' => date('c')