fix(deployments): retry transient GitHub token and clone failures

Retry the installation token request on GitHub 5xx and connection errors,
and report the HTTP status when GitHub sends no error message. Retry the
repository import when SSH drops the connection (exit code 255), after
stopping the interrupted clone and removing the partial checkout.

Closes #8004

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2026-10-15 22:06:57 +02:00
co-authored by Claude Opus 5.5
parent 19430b461a
commit 00678a12f0
4 changed files with 177 additions and 7 deletions
+11 -2
View File
@@ -4,6 +4,8 @@ use App\Models\GithubApp;
use App\Models\PrivateKey;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
@@ -195,13 +197,20 @@ function generateGithubToken(GithubApp $source, string $type)
return match ($type) {
'jwt' => $jwt,
'installation' => (function () use ($source, $jwt) {
// GitHub sometimes answers with a 5xx page or drops the connection; a new token request is harmless.
$response = Http::GitSource($source->api_url)->withHeaders([
'Authorization' => "Bearer $jwt",
'Accept' => 'application/vnd.github.machine-man-preview+json',
])->post("{$source->api_url}/app/installations/{$source->installation_id}/access_tokens");
])->retry(
3,
fn (int $attempt) => $attempt * 1000,
fn (Throwable $exception) => $exception instanceof ConnectionException
|| ($exception instanceof RequestException && $exception->response->serverError()),
throw: false,
)->post("{$source->api_url}/app/installations/{$source->installation_id}/access_tokens");
if (! $response->successful()) {
$error = data_get($response->json(), 'message', 'no error message found');
$error = data_get($response->json(), 'message', "HTTP {$response->status()}");
if ($error === 'Not Found') {
$error = 'Repository not found. Is it moved or deleted?';
}