From 76c511356aa333fe9a1cd146586943c19f928dc4 Mon Sep 17 00:00:00 2001 From: selmankoc Date: Mon, 13 Apr 2026 10:35:44 +0300 Subject: [PATCH 1/4] Enhance NuGet package push script to handle quota exceeded errors with retry logic. Added configurable retry count and delays for improved resilience during package pushes. --- nupkg/push_packages.ps1 | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/nupkg/push_packages.ps1 b/nupkg/push_packages.ps1 index 6fa91a5599..9f83badbb8 100644 --- a/nupkg/push_packages.ps1 +++ b/nupkg/push_packages.ps1 @@ -11,6 +11,8 @@ $i = 0 $errorCount = 0 $totalProjectsCount = $projects.length $nugetUrl = "https://api.nuget.org/v3/index.json" +$maxQuotaRetryCount = 3 +$quotaRetryDelaysInSeconds = @(30, 60, 120) Set-Location $packFolder foreach($project in $projects) { @@ -24,7 +26,31 @@ foreach($project in $projects) { if ($nugetPackageExists) { - dotnet nuget push $nugetPackageName --skip-duplicate -s $nugetUrl --api-key "$apiKey" + $attempt = 0 + while ($true) + { + $attempt += 1 + $pushOutput = dotnet nuget push $nugetPackageName --skip-duplicate -s $nugetUrl --api-key "$apiKey" 2>&1 + $pushOutput | ForEach-Object { Write-Host $_ } + + $pushSucceeded = $LASTEXITCODE -eq 0 + if ($pushSucceeded) + { + break + } + + $quotaExceeded = ($pushOutput | Out-String) -match "403 \(Quota Exceeded\)" + $canRetry = $quotaExceeded -and $attempt -le $maxQuotaRetryCount + + if (-not $canRetry) + { + break + } + + $retryDelay = $quotaRetryDelaysInSeconds[$attempt - 1] + Write-Warning "NuGet quota exceeded for $nugetPackageName. Retrying in $retryDelay seconds (retry $attempt/$maxQuotaRetryCount)..." + Start-Sleep -Seconds $retryDelay + } #Write-Host ("Deleting package from local: " + $nugetPackageName) #Remove-Item $nugetPackageName -Force } From bb587dcc30c13740bda798a7e5977d0dd25a9fef Mon Sep 17 00:00:00 2001 From: selmankoc Date: Mon, 13 Apr 2026 12:02:44 +0300 Subject: [PATCH 2/4] Update NuGet package push script to improve error handling for 4xx responses. Changed warning message to reflect the new error condition and ensure clarity during retries. --- nupkg/push_packages.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nupkg/push_packages.ps1 b/nupkg/push_packages.ps1 index 9f83badbb8..5a66813ad9 100644 --- a/nupkg/push_packages.ps1 +++ b/nupkg/push_packages.ps1 @@ -39,8 +39,8 @@ foreach($project in $projects) { break } - $quotaExceeded = ($pushOutput | Out-String) -match "403 \(Quota Exceeded\)" - $canRetry = $quotaExceeded -and $attempt -le $maxQuotaRetryCount + $clientError = ($pushOutput | Out-String) -match "Response status code does not indicate success:\s*4\d\d" + $canRetry = $clientError -and $attempt -le $maxQuotaRetryCount if (-not $canRetry) { @@ -48,7 +48,7 @@ foreach($project in $projects) { } $retryDelay = $quotaRetryDelaysInSeconds[$attempt - 1] - Write-Warning "NuGet quota exceeded for $nugetPackageName. Retrying in $retryDelay seconds (retry $attempt/$maxQuotaRetryCount)..." + Write-Warning "NuGet push returned a 4xx response for $nugetPackageName. Retrying in $retryDelay seconds (retry $attempt/$maxQuotaRetryCount)..." Start-Sleep -Seconds $retryDelay } #Write-Host ("Deleting package from local: " + $nugetPackageName) From c120d10731be0ae3f45df78aeba12b2445f6c428 Mon Sep 17 00:00:00 2001 From: selmankoc Date: Mon, 13 Apr 2026 12:23:09 +0300 Subject: [PATCH 3/4] Enhance NuGet package push scripts to include Discord webhook notifications for failed package pushes. Added error tracking for failed packages and improved error handling during push attempts. --- nupkg/push-nightly-packages-myget.ps1 | 80 ++++++++++++++++++++++++++- nupkg/push_packages.ps1 | 30 ++++++++++ 2 files changed, 108 insertions(+), 2 deletions(-) diff --git a/nupkg/push-nightly-packages-myget.ps1 b/nupkg/push-nightly-packages-myget.ps1 index ff3eb93774..5496bcfd74 100644 --- a/nupkg/push-nightly-packages-myget.ps1 +++ b/nupkg/push-nightly-packages-myget.ps1 @@ -1,6 +1,7 @@ param( [string]$source, - [string]$apikey + [string]$apikey, + [string]$discordWebhookUrl ) if (!$source) @@ -13,4 +14,79 @@ if (!$apikey) $apikey = "dummy" } -dotnet nuget push '*.nupkg' -s $source --skip-duplicate --api-key $apikey \ No newline at end of file +if (!$discordWebhookUrl) +{ + $discordWebhookUrl = $env:DISCORD_WEBHOOK_URL +} + +$maxRetryCount = 3 +$retryDelaysInSeconds = @(30, 60, 120) +$failedPackages = @() + +$packages = Get-ChildItem -Filter *.nupkg | Sort-Object Name + +foreach ($package in $packages) +{ + $packageName = $package.Name + Write-Host "Pushing nightly package: $packageName" + + $attempt = 0 + $pushSucceeded = $false + while ($true) + { + $attempt += 1 + $pushOutput = dotnet nuget push $packageName -s $source --skip-duplicate --api-key $apikey 2>&1 + $pushOutput | ForEach-Object { Write-Host $_ } + + $pushSucceeded = $LASTEXITCODE -eq 0 + if ($pushSucceeded) + { + break + } + + $clientError = ($pushOutput | Out-String) -match "Response status code does not indicate success:\s*4\d\d" + $canRetry = $clientError -and $attempt -le $maxRetryCount + if (-not $canRetry) + { + break + } + + $retryDelay = $retryDelaysInSeconds[$attempt - 1] + Write-Warning "NuGet push returned a 4xx response for $packageName. Retrying in $retryDelay seconds (retry $attempt/$maxRetryCount)..." + Start-Sleep -Seconds $retryDelay + } + + if (-not $pushSucceeded) + { + Write-Host ("********** ERROR PUSH FAILED: " + $packageName) -ForegroundColor red + $failedPackages += $packageName + } +} + +if ($failedPackages.Count -gt 0) +{ + $errorCount = $failedPackages.Count + Write-Host ("******* $errorCount error(s) occured *******") -ForegroundColor red + + if (-not [string]::IsNullOrWhiteSpace($discordWebhookUrl)) + { + try + { + $messageLines = @( + "Nightly NuGet push completed with failures (ABP).", + "Failed package count: $errorCount", + "Failed packages:" + ) + ($failedPackages | ForEach-Object { "- $_" }) + + $payload = @{ content = ($messageLines -join "`n") } | ConvertTo-Json -Compress + Invoke-RestMethod -Uri $discordWebhookUrl -Method Post -ContentType "application/json" -Body $payload | Out-Null + Write-Host "Discord notification sent for failed packages." + } + catch + { + Write-Warning "Failed to send Discord webhook notification: $($_.Exception.Message)" + } + } + + exit 1 +} \ No newline at end of file diff --git a/nupkg/push_packages.ps1 b/nupkg/push_packages.ps1 index 5a66813ad9..db70b2f8e3 100644 --- a/nupkg/push_packages.ps1 +++ b/nupkg/push_packages.ps1 @@ -1,6 +1,7 @@ . ".\common.ps1" $apiKey = $args[0] +$discordWebhookUrl = if ($args.Length -gt 1) { $args[1] } else { $env:DISCORD_WEBHOOK_URL } # Get the version [xml]$commonPropsXml = Get-Content (Join-Path $rootFolder "common.props") @@ -9,6 +10,7 @@ $version = $commonPropsXml.Project.PropertyGroup.Version # Publish all packages $i = 0 $errorCount = 0 +$failedPackages = @() $totalProjectsCount = $projects.length $nugetUrl = "https://api.nuget.org/v3/index.json" $maxQuotaRetryCount = 3 @@ -27,6 +29,7 @@ foreach($project in $projects) { if ($nugetPackageExists) { $attempt = 0 + $pushSucceeded = $false while ($true) { $attempt += 1 @@ -51,6 +54,13 @@ foreach($project in $projects) { Write-Warning "NuGet push returned a 4xx response for $nugetPackageName. Retrying in $retryDelay seconds (retry $attempt/$maxQuotaRetryCount)..." Start-Sleep -Seconds $retryDelay } + + if (-not $pushSucceeded) + { + Write-Host ("********** ERROR PUSH FAILED: " + $nugetPackageName) -ForegroundColor red + $errorCount += 1 + $failedPackages += $nugetPackageName + } #Write-Host ("Deleting package from local: " + $nugetPackageName) #Remove-Item $nugetPackageName -Force } @@ -67,4 +77,24 @@ foreach($project in $projects) { if ($errorCount > 0) { Write-Host ("******* $errorCount error(s) occured *******") -ForegroundColor red + + if (-not [string]::IsNullOrWhiteSpace($discordWebhookUrl)) + { + try + { + $messageLines = @( + "NuGet push completed with failures (ABP).", + "Failed package count: $errorCount", + "Failed packages:" + ) + ($failedPackages | ForEach-Object { "- $_" }) + + $payload = @{ content = ($messageLines -join "`n") } | ConvertTo-Json -Compress + Invoke-RestMethod -Uri $discordWebhookUrl -Method Post -ContentType "application/json" -Body $payload | Out-Null + Write-Info "Discord notification sent for failed packages." + } + catch + { + Write-Warning "Failed to send Discord webhook notification: $($_.Exception.Message)" + } + } } From e8320a524a012bda2727489d07563a11c0622017 Mon Sep 17 00:00:00 2001 From: selmankoc Date: Mon, 13 Apr 2026 12:29:13 +0300 Subject: [PATCH 4/4] Remove Discord webhook notification logic from NuGet package push scripts. Simplified error handling by exiting with a status code on failures without sending notifications. --- nupkg/push-nightly-packages-myget.ps1 | 29 +-------------------------- nupkg/push_packages.ps1 | 22 +------------------- 2 files changed, 2 insertions(+), 49 deletions(-) diff --git a/nupkg/push-nightly-packages-myget.ps1 b/nupkg/push-nightly-packages-myget.ps1 index 5496bcfd74..3127d21f0c 100644 --- a/nupkg/push-nightly-packages-myget.ps1 +++ b/nupkg/push-nightly-packages-myget.ps1 @@ -1,7 +1,6 @@ param( [string]$source, - [string]$apikey, - [string]$discordWebhookUrl + [string]$apikey ) if (!$source) @@ -14,11 +13,6 @@ if (!$apikey) $apikey = "dummy" } -if (!$discordWebhookUrl) -{ - $discordWebhookUrl = $env:DISCORD_WEBHOOK_URL -} - $maxRetryCount = 3 $retryDelaysInSeconds = @(30, 60, 120) $failedPackages = @() @@ -67,26 +61,5 @@ if ($failedPackages.Count -gt 0) { $errorCount = $failedPackages.Count Write-Host ("******* $errorCount error(s) occured *******") -ForegroundColor red - - if (-not [string]::IsNullOrWhiteSpace($discordWebhookUrl)) - { - try - { - $messageLines = @( - "Nightly NuGet push completed with failures (ABP).", - "Failed package count: $errorCount", - "Failed packages:" - ) + ($failedPackages | ForEach-Object { "- $_" }) - - $payload = @{ content = ($messageLines -join "`n") } | ConvertTo-Json -Compress - Invoke-RestMethod -Uri $discordWebhookUrl -Method Post -ContentType "application/json" -Body $payload | Out-Null - Write-Host "Discord notification sent for failed packages." - } - catch - { - Write-Warning "Failed to send Discord webhook notification: $($_.Exception.Message)" - } - } - exit 1 } \ No newline at end of file diff --git a/nupkg/push_packages.ps1 b/nupkg/push_packages.ps1 index db70b2f8e3..005610a346 100644 --- a/nupkg/push_packages.ps1 +++ b/nupkg/push_packages.ps1 @@ -1,7 +1,6 @@ . ".\common.ps1" $apiKey = $args[0] -$discordWebhookUrl = if ($args.Length -gt 1) { $args[1] } else { $env:DISCORD_WEBHOOK_URL } # Get the version [xml]$commonPropsXml = Get-Content (Join-Path $rootFolder "common.props") @@ -77,24 +76,5 @@ foreach($project in $projects) { if ($errorCount > 0) { Write-Host ("******* $errorCount error(s) occured *******") -ForegroundColor red - - if (-not [string]::IsNullOrWhiteSpace($discordWebhookUrl)) - { - try - { - $messageLines = @( - "NuGet push completed with failures (ABP).", - "Failed package count: $errorCount", - "Failed packages:" - ) + ($failedPackages | ForEach-Object { "- $_" }) - - $payload = @{ content = ($messageLines -join "`n") } | ConvertTo-Json -Compress - Invoke-RestMethod -Uri $discordWebhookUrl -Method Post -ContentType "application/json" -Body $payload | Out-Null - Write-Info "Discord notification sent for failed packages." - } - catch - { - Write-Warning "Failed to send Discord webhook notification: $($_.Exception.Message)" - } - } + exit 1 }