fix(release): retry uploads with backoff + drop Gitea workflows
Gitea/nginx intermittently returns 504 on large multipart uploads even when curl successfully streamed the body. Add up to 4 retries with exponential backoff (15s/45s/2m/5m). Before each retry, check whether the asset is actually present server-side at the expected size — Gitea sometimes accepts the body but times out the response, so the file is already there. Also drop .gitea/workflows/* — we use release.ps1 locally and Gitea Actions runners are not configured, so every push was leaving queued/ failed workflow runs in the Actions tab. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -157,21 +157,66 @@ if ($curlCmd) {
|
||||
}
|
||||
}
|
||||
|
||||
$maxRetries = 4
|
||||
$backoffs = @(15, 45, 120, 300) # seconds between attempts
|
||||
|
||||
foreach ($asset in @($installer, $blockmap, $manifest)) {
|
||||
$name = Split-Path $asset -Leaf
|
||||
$size = (Get-Item $asset).Length
|
||||
Write-Host ("Uploading {0} ({1:N1} MB)..." -f $name, ($size / 1MB)) -ForegroundColor Cyan
|
||||
$uri = "$apiBase/repos/$repoOwner/$repoName/releases/$($release.id)/assets?name=$([uri]::EscapeDataString($name))"
|
||||
# -f: fail on HTTP errors; -s -S: silent but show errors; --data-binary @file
|
||||
& $curl `
|
||||
--fail-with-body `
|
||||
--silent --show-error `
|
||||
-H "Authorization: token $env:GITEA_TOKEN" `
|
||||
-H "Content-Type: application/octet-stream" `
|
||||
--data-binary "@$asset" `
|
||||
$uri
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Error "Upload failed for $name (curl exit $LASTEXITCODE)"
|
||||
|
||||
$attempt = 0
|
||||
$uploaded = $false
|
||||
while (-not $uploaded -and $attempt -le $maxRetries) {
|
||||
if ($attempt -gt 0) {
|
||||
$wait = $backoffs[[Math]::Min($attempt - 1, $backoffs.Length - 1)]
|
||||
Write-Host (" Retrying in {0}s (attempt {1}/{2})..." -f $wait, ($attempt + 1), ($maxRetries + 1)) -ForegroundColor Yellow
|
||||
Start-Sleep -Seconds $wait
|
||||
|
||||
# Re-check whether prior attempt actually succeeded server-side before
|
||||
# 504-ing the client. If asset is already there, treat as success.
|
||||
try {
|
||||
$check = Invoke-RestMethod `
|
||||
-Uri "$apiBase/repos/$repoOwner/$repoName/releases/$($release.id)/assets" `
|
||||
-Method Get -Headers $headers
|
||||
$existing = $check | Where-Object { $_.name -eq $name }
|
||||
if ($existing -and $existing.size -eq $size) {
|
||||
Write-Host " Asset already present server-side ($($existing.size) bytes) — skipping retry." -ForegroundColor DarkGray
|
||||
$uploaded = $true
|
||||
break
|
||||
}
|
||||
# If asset is present but with wrong size (half-uploaded), delete first.
|
||||
if ($existing) {
|
||||
Write-Host " Removing partial asset id=$($existing.id) ($($existing.size) bytes) before retry..." -ForegroundColor DarkGray
|
||||
Invoke-RestMethod `
|
||||
-Uri "$apiBase/repos/$repoOwner/$repoName/releases/$($release.id)/assets/$($existing.id)" `
|
||||
-Method Delete -Headers $headers | Out-Null
|
||||
}
|
||||
} catch {
|
||||
# If the list call itself fails, just proceed with the retry.
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ("Uploading {0} ({1:N1} MB)..." -f $name, ($size / 1MB)) -ForegroundColor Cyan
|
||||
& $curl `
|
||||
--fail-with-body `
|
||||
--silent --show-error `
|
||||
--connect-timeout 30 `
|
||||
--max-time 900 `
|
||||
-H "Authorization: token $env:GITEA_TOKEN" `
|
||||
-H "Content-Type: application/octet-stream" `
|
||||
--data-binary "@$asset" `
|
||||
$uri
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
$uploaded = $true
|
||||
} else {
|
||||
Write-Host " curl exit $LASTEXITCODE — will retry." -ForegroundColor Yellow
|
||||
$attempt++
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $uploaded) {
|
||||
Write-Error "Upload failed for $name after $($maxRetries + 1) attempts."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user