Skip to content

Commit

Permalink
Add resilience to publishing (#3726)
Browse files Browse the repository at this point in the history
This PR should fix some instabilities when publishing many apps to an
online service.
It fixes:
- A constant renewal of the authcontext when expired
- Some times the Nav.Upload API call resulted in an error in the server
- but the app was still uploaded

Fixes #3628

---------

Co-authored-by: freddydk <[email protected]>
  • Loading branch information
freddydk and freddydk authored Oct 16, 2024
1 parent 3858eb1 commit 3d959c0
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 14 deletions.
1 change: 1 addition & 0 deletions ReleaseNotes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Issue 3621 New-AadAppsForBc shows "-includeEmailAadApp is deprecated. Use -inclu
Issue 3718 Business Central Web Client Fails to Load After Updating to Windows 24H2
Issue #3703 Missing Function Download-BcEnvironmentInstalledExtensionToFolder
Fix for issue 1262 in AL-Go for GitHub
Fix instabilities during Publish-PerTenantExtensionApps

6.0.25
Fix issue where generateDependencyArtifact doesn't result in dependencies if useCompilerFolder is true or filesonly containers are used in Run-AlPipeline
Expand Down
44 changes: 30 additions & 14 deletions Saas/Publish-PerTenantExtensionApps.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ function Publish-PerTenantExtensionApps {
$telemetryScope = InitTelemetryScope -name $MyInvocation.InvocationName -parameterValues $PSBoundParameters -includeParameters @()
try {

$script:authContext = Renew-BcAuthContext -bcAuthContext $bcAuthContext

function GetAuthHeaders {
$bcAuthContext = Renew-BcAuthContext -bcAuthContext $bcAuthContext
return @{ "Authorization" = "Bearer $($bcAuthContext.AccessToken)" }
$script:authContext = Renew-BcAuthContext -bcAuthContext $script:authContext
return @{ "Authorization" = "Bearer $($script:authContext.AccessToken)" }
}

$newLine = @{}
Expand Down Expand Up @@ -131,7 +133,7 @@ try {
$streamHeader = @{ "Content-Type" = 'application/octet-stream'}
try {
Sort-AppFilesByDependencies -appFiles $appFiles -excludeRuntimePackages | ForEach-Object {
Write-Host -NoNewline "$([System.IO.Path]::GetFileName($_)) - "
Write-Host @newline "$([System.IO.Path]::GetFileName($_)) - "
$appJson = Get-AppJsonFromAppFile -appFile $_

$existingApp = $extensions | Where-Object { $_.id -eq $appJson.id -and $_.isInstalled }
Expand Down Expand Up @@ -185,56 +187,69 @@ try {
Invoke-RestMethod `
-Method Post `
-Uri "$automationApiUrl/companies($companyId)/extensionUpload($($extensionUpload.systemId))/Microsoft.NAV.upload" `
-Headers ((GetAuthHeaders) + $ifMatchHeader) | Out-Null
-Headers ((GetAuthHeaders) + $ifMatchHeader) `
-ErrorAction SilentlyContinue | Out-Null
Write-Host @newLine "."
$completed = $false
$errCount = 0
$sleepSeconds = 30
$lastStatus = ''
while (!$completed)
{
Start-Sleep -Seconds $sleepSeconds
try {
$extensionDeploymentStatusResponse = Invoke-WebRequest -Headers (GetAuthHeaders) -Method Get -Uri "$automationApiUrl/companies($companyId)/extensionDeploymentStatus" -UseBasicParsing
$extensionDeploymentStatuses = (ConvertFrom-Json $extensionDeploymentStatusResponse.Content).value

$completed = $true
$extensionDeploymentStatuses | Where-Object { $_.publisher -eq $appJson.publisher -and $_.name -eq $appJson.name -and $_.appVersion -eq $appJson.version } | % {
$thisExtension = $extensionDeploymentStatuses | Where-Object { $_.publisher -eq $appJson.publisher -and $_.name -eq $appJson.name -and $_.appVersion -eq $appJson.version }
if ($null -eq $thisExtension) {
throw "Unable to find extension deployment status"
}
$thisExtension | ForEach-Object {
if ($_.status -ne $lastStatus) {
if (!$useNewLine) { Write-Host }
Write-Host @newLine $_.status
$lastStatus = $_.status
}
if ($_.status -eq "InProgress") {
$errCount = 0
$sleepSeconds = 5
Write-Host @newLine "."
$completed = $false
}
elseif ($_.Status -eq "Unknown") {
throw "Unknown Error"
}
elseif ($_.Status -ne "Completed") {
elseif ($_.Status -eq "Completed") {
if (!$useNewLine) { Write-Host }
$completed = $true
}
else {
$errCount = 5
throw $_.status
}
}
$errCount = 0
$sleepSeconds = 5
}
catch {
if (!$useNewLine) { Write-Host }
if ($errCount++ -gt 4) {
Write-Host $_.Exception.Message
throw "Unable to publish app. Please open the Extension Deployment Status Details page in Business Central to see the detailed error message."
}
$sleepSeconds += $sleepSeconds
$completed = $false
Write-Host "Error: $($_.Exception.Message). Retrying in $sleepSeconds seconds"
}
}
if ($completed) {
Write-Host "completed"
}
}
}
}
catch [System.Net.WebException],[System.Net.Http.HttpRequestException] {
if (!$useNewLine) { Write-Host }
Write-Host "ERROR $($_.Exception.Message)"
Write-Host $_.ScriptStackTrace
throw (GetExtendedErrorMessage $_)
}
catch {
if (!$useNewLine) { Write-Host }
Write-Host "ERROR: $($_.Exception.Message) [$($_.Exception.GetType().FullName)]"
throw
}
Expand Down Expand Up @@ -264,6 +279,7 @@ catch {
throw
}
finally {
$script:authContext = $null
TrackTrace -telemetryScope $telemetryScope
}
}
Expand Down

0 comments on commit 3d959c0

Please sign in to comment.